linux/drivers/gpu/drm/omapdrm/omap_drv.c
<<
>>
Prefs
   1/*
   2 * drivers/gpu/drm/omapdrm/omap_drv.c
   3 *
   4 * Copyright (C) 2011 Texas Instruments
   5 * Author: Rob Clark <rob@ti.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU General Public License version 2 as published by
   9 * the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along with
  17 * this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include <linux/wait.h>
  21
  22#include <drm/drm_atomic.h>
  23#include <drm/drm_atomic_helper.h>
  24#include <drm/drm_crtc_helper.h>
  25#include <drm/drm_fb_helper.h>
  26
  27#include "omap_dmm_tiler.h"
  28#include "omap_drv.h"
  29
  30#define DRIVER_NAME             MODULE_NAME
  31#define DRIVER_DESC             "OMAP DRM"
  32#define DRIVER_DATE             "20110917"
  33#define DRIVER_MAJOR            1
  34#define DRIVER_MINOR            0
  35#define DRIVER_PATCHLEVEL       0
  36
  37static int num_crtc = CONFIG_DRM_OMAP_NUM_CRTCS;
  38
  39MODULE_PARM_DESC(num_crtc, "Number of overlays to use as CRTCs");
  40module_param(num_crtc, int, 0600);
  41
  42/*
  43 * mode config funcs
  44 */
  45
  46/* Notes about mapping DSS and DRM entities:
  47 *    CRTC:        overlay
  48 *    encoder:     manager.. with some extension to allow one primary CRTC
  49 *                 and zero or more video CRTC's to be mapped to one encoder?
  50 *    connector:   dssdev.. manager can be attached/detached from different
  51 *                 devices
  52 */
  53
  54static void omap_fb_output_poll_changed(struct drm_device *dev)
  55{
  56        struct omap_drm_private *priv = dev->dev_private;
  57        DBG("dev=%p", dev);
  58        if (priv->fbdev)
  59                drm_fb_helper_hotplug_event(priv->fbdev);
  60}
  61
  62struct omap_atomic_state_commit {
  63        struct work_struct work;
  64        struct drm_device *dev;
  65        struct drm_atomic_state *state;
  66        u32 crtcs;
  67};
  68
  69static void omap_atomic_wait_for_completion(struct drm_device *dev,
  70                                            struct drm_atomic_state *old_state)
  71{
  72        struct drm_crtc_state *old_crtc_state;
  73        struct drm_crtc *crtc;
  74        unsigned int i;
  75        int ret;
  76
  77        for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
  78                if (!crtc->state->enable)
  79                        continue;
  80
  81                ret = omap_crtc_wait_pending(crtc);
  82
  83                if (!ret)
  84                        dev_warn(dev->dev,
  85                                 "atomic complete timeout (pipe %u)!\n", i);
  86        }
  87}
  88
  89static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
  90{
  91        struct drm_device *dev = commit->dev;
  92        struct omap_drm_private *priv = dev->dev_private;
  93        struct drm_atomic_state *old_state = commit->state;
  94
  95        /* Apply the atomic update. */
  96        dispc_runtime_get();
  97
  98        drm_atomic_helper_commit_modeset_disables(dev, old_state);
  99        drm_atomic_helper_commit_planes(dev, old_state, false);
 100        drm_atomic_helper_commit_modeset_enables(dev, old_state);
 101
 102        omap_atomic_wait_for_completion(dev, old_state);
 103
 104        drm_atomic_helper_cleanup_planes(dev, old_state);
 105
 106        dispc_runtime_put();
 107
 108        drm_atomic_state_free(old_state);
 109
 110        /* Complete the commit, wake up any waiter. */
 111        spin_lock(&priv->commit.lock);
 112        priv->commit.pending &= ~commit->crtcs;
 113        spin_unlock(&priv->commit.lock);
 114
 115        wake_up_all(&priv->commit.wait);
 116
 117        kfree(commit);
 118}
 119
 120static void omap_atomic_work(struct work_struct *work)
 121{
 122        struct omap_atomic_state_commit *commit =
 123                container_of(work, struct omap_atomic_state_commit, work);
 124
 125        omap_atomic_complete(commit);
 126}
 127
 128static bool omap_atomic_is_pending(struct omap_drm_private *priv,
 129                                   struct omap_atomic_state_commit *commit)
 130{
 131        bool pending;
 132
 133        spin_lock(&priv->commit.lock);
 134        pending = priv->commit.pending & commit->crtcs;
 135        spin_unlock(&priv->commit.lock);
 136
 137        return pending;
 138}
 139
 140static int omap_atomic_commit(struct drm_device *dev,
 141                              struct drm_atomic_state *state, bool async)
 142{
 143        struct omap_drm_private *priv = dev->dev_private;
 144        struct omap_atomic_state_commit *commit;
 145        unsigned int i;
 146        int ret;
 147
 148        ret = drm_atomic_helper_prepare_planes(dev, state);
 149        if (ret)
 150                return ret;
 151
 152        /* Allocate the commit object. */
 153        commit = kzalloc(sizeof(*commit), GFP_KERNEL);
 154        if (commit == NULL) {
 155                ret = -ENOMEM;
 156                goto error;
 157        }
 158
 159        INIT_WORK(&commit->work, omap_atomic_work);
 160        commit->dev = dev;
 161        commit->state = state;
 162
 163        /* Wait until all affected CRTCs have completed previous commits and
 164         * mark them as pending.
 165         */
 166        for (i = 0; i < dev->mode_config.num_crtc; ++i) {
 167                if (state->crtcs[i])
 168                        commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
 169        }
 170
 171        wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));
 172
 173        spin_lock(&priv->commit.lock);
 174        priv->commit.pending |= commit->crtcs;
 175        spin_unlock(&priv->commit.lock);
 176
 177        /* Swap the state, this is the point of no return. */
 178        drm_atomic_helper_swap_state(dev, state);
 179
 180        if (async)
 181                schedule_work(&commit->work);
 182        else
 183                omap_atomic_complete(commit);
 184
 185        return 0;
 186
 187error:
 188        drm_atomic_helper_cleanup_planes(dev, state);
 189        return ret;
 190}
 191
 192static const struct drm_mode_config_funcs omap_mode_config_funcs = {
 193        .fb_create = omap_framebuffer_create,
 194        .output_poll_changed = omap_fb_output_poll_changed,
 195        .atomic_check = drm_atomic_helper_check,
 196        .atomic_commit = omap_atomic_commit,
 197};
 198
 199static int get_connector_type(struct omap_dss_device *dssdev)
 200{
 201        switch (dssdev->type) {
 202        case OMAP_DISPLAY_TYPE_HDMI:
 203                return DRM_MODE_CONNECTOR_HDMIA;
 204        case OMAP_DISPLAY_TYPE_DVI:
 205                return DRM_MODE_CONNECTOR_DVID;
 206        default:
 207                return DRM_MODE_CONNECTOR_Unknown;
 208        }
 209}
 210
 211static bool channel_used(struct drm_device *dev, enum omap_channel channel)
 212{
 213        struct omap_drm_private *priv = dev->dev_private;
 214        int i;
 215
 216        for (i = 0; i < priv->num_crtcs; i++) {
 217                struct drm_crtc *crtc = priv->crtcs[i];
 218
 219                if (omap_crtc_channel(crtc) == channel)
 220                        return true;
 221        }
 222
 223        return false;
 224}
 225static void omap_disconnect_dssdevs(void)
 226{
 227        struct omap_dss_device *dssdev = NULL;
 228
 229        for_each_dss_dev(dssdev)
 230                dssdev->driver->disconnect(dssdev);
 231}
 232
 233static int omap_connect_dssdevs(void)
 234{
 235        int r;
 236        struct omap_dss_device *dssdev = NULL;
 237        bool no_displays = true;
 238
 239        for_each_dss_dev(dssdev) {
 240                r = dssdev->driver->connect(dssdev);
 241                if (r == -EPROBE_DEFER) {
 242                        omap_dss_put_device(dssdev);
 243                        goto cleanup;
 244                } else if (r) {
 245                        dev_warn(dssdev->dev, "could not connect display: %s\n",
 246                                dssdev->name);
 247                } else {
 248                        no_displays = false;
 249                }
 250        }
 251
 252        if (no_displays)
 253                return -EPROBE_DEFER;
 254
 255        return 0;
 256
 257cleanup:
 258        /*
 259         * if we are deferring probe, we disconnect the devices we previously
 260         * connected
 261         */
 262        omap_disconnect_dssdevs();
 263
 264        return r;
 265}
 266
 267static int omap_modeset_create_crtc(struct drm_device *dev, int id,
 268                                    enum omap_channel channel)
 269{
 270        struct omap_drm_private *priv = dev->dev_private;
 271        struct drm_plane *plane;
 272        struct drm_crtc *crtc;
 273
 274        plane = omap_plane_init(dev, id, DRM_PLANE_TYPE_PRIMARY);
 275        if (IS_ERR(plane))
 276                return PTR_ERR(plane);
 277
 278        crtc = omap_crtc_init(dev, plane, channel, id);
 279
 280        BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs));
 281        priv->crtcs[id] = crtc;
 282        priv->num_crtcs++;
 283
 284        priv->planes[id] = plane;
 285        priv->num_planes++;
 286
 287        return 0;
 288}
 289
 290static int omap_modeset_init_properties(struct drm_device *dev)
 291{
 292        struct omap_drm_private *priv = dev->dev_private;
 293
 294        if (priv->has_dmm) {
 295                dev->mode_config.rotation_property =
 296                        drm_mode_create_rotation_property(dev,
 297                                BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_90) |
 298                                BIT(DRM_ROTATE_180) | BIT(DRM_ROTATE_270) |
 299                                BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y));
 300                if (!dev->mode_config.rotation_property)
 301                        return -ENOMEM;
 302        }
 303
 304        priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0, 3);
 305        if (!priv->zorder_prop)
 306                return -ENOMEM;
 307
 308        return 0;
 309}
 310
 311static int omap_modeset_init(struct drm_device *dev)
 312{
 313        struct omap_drm_private *priv = dev->dev_private;
 314        struct omap_dss_device *dssdev = NULL;
 315        int num_ovls = dss_feat_get_num_ovls();
 316        int num_mgrs = dss_feat_get_num_mgrs();
 317        int num_crtcs;
 318        int i, id = 0;
 319        int ret;
 320
 321        drm_mode_config_init(dev);
 322
 323        omap_drm_irq_install(dev);
 324
 325        ret = omap_modeset_init_properties(dev);
 326        if (ret < 0)
 327                return ret;
 328
 329        /*
 330         * We usually don't want to create a CRTC for each manager, at least
 331         * not until we have a way to expose private planes to userspace.
 332         * Otherwise there would not be enough video pipes left for drm planes.
 333         * We use the num_crtc argument to limit the number of crtcs we create.
 334         */
 335        num_crtcs = min3(num_crtc, num_mgrs, num_ovls);
 336
 337        dssdev = NULL;
 338
 339        for_each_dss_dev(dssdev) {
 340                struct drm_connector *connector;
 341                struct drm_encoder *encoder;
 342                enum omap_channel channel;
 343                struct omap_dss_device *out;
 344
 345                if (!omapdss_device_is_connected(dssdev))
 346                        continue;
 347
 348                encoder = omap_encoder_init(dev, dssdev);
 349
 350                if (!encoder) {
 351                        dev_err(dev->dev, "could not create encoder: %s\n",
 352                                        dssdev->name);
 353                        return -ENOMEM;
 354                }
 355
 356                connector = omap_connector_init(dev,
 357                                get_connector_type(dssdev), dssdev, encoder);
 358
 359                if (!connector) {
 360                        dev_err(dev->dev, "could not create connector: %s\n",
 361                                        dssdev->name);
 362                        return -ENOMEM;
 363                }
 364
 365                BUG_ON(priv->num_encoders >= ARRAY_SIZE(priv->encoders));
 366                BUG_ON(priv->num_connectors >= ARRAY_SIZE(priv->connectors));
 367
 368                priv->encoders[priv->num_encoders++] = encoder;
 369                priv->connectors[priv->num_connectors++] = connector;
 370
 371                drm_mode_connector_attach_encoder(connector, encoder);
 372
 373                /*
 374                 * if we have reached the limit of the crtcs we are allowed to
 375                 * create, let's not try to look for a crtc for this
 376                 * panel/encoder and onwards, we will, of course, populate the
 377                 * the possible_crtcs field for all the encoders with the final
 378                 * set of crtcs we create
 379                 */
 380                if (id == num_crtcs)
 381                        continue;
 382
 383                /*
 384                 * get the recommended DISPC channel for this encoder. For now,
 385                 * we only try to get create a crtc out of the recommended, the
 386                 * other possible channels to which the encoder can connect are
 387                 * not considered.
 388                 */
 389
 390                out = omapdss_find_output_from_display(dssdev);
 391                channel = out->dispc_channel;
 392                omap_dss_put_device(out);
 393
 394                /*
 395                 * if this channel hasn't already been taken by a previously
 396                 * allocated crtc, we create a new crtc for it
 397                 */
 398                if (!channel_used(dev, channel)) {
 399                        ret = omap_modeset_create_crtc(dev, id, channel);
 400                        if (ret < 0) {
 401                                dev_err(dev->dev,
 402                                        "could not create CRTC (channel %u)\n",
 403                                        channel);
 404                                return ret;
 405                        }
 406
 407                        id++;
 408                }
 409        }
 410
 411        /*
 412         * we have allocated crtcs according to the need of the panels/encoders,
 413         * adding more crtcs here if needed
 414         */
 415        for (; id < num_crtcs; id++) {
 416
 417                /* find a free manager for this crtc */
 418                for (i = 0; i < num_mgrs; i++) {
 419                        if (!channel_used(dev, i))
 420                                break;
 421                }
 422
 423                if (i == num_mgrs) {
 424                        /* this shouldn't really happen */
 425                        dev_err(dev->dev, "no managers left for crtc\n");
 426                        return -ENOMEM;
 427                }
 428
 429                ret = omap_modeset_create_crtc(dev, id, i);
 430                if (ret < 0) {
 431                        dev_err(dev->dev,
 432                                "could not create CRTC (channel %u)\n", i);
 433                        return ret;
 434                }
 435        }
 436
 437        /*
 438         * Create normal planes for the remaining overlays:
 439         */
 440        for (; id < num_ovls; id++) {
 441                struct drm_plane *plane;
 442
 443                plane = omap_plane_init(dev, id, DRM_PLANE_TYPE_OVERLAY);
 444                if (IS_ERR(plane))
 445                        return PTR_ERR(plane);
 446
 447                BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes));
 448                priv->planes[priv->num_planes++] = plane;
 449        }
 450
 451        for (i = 0; i < priv->num_encoders; i++) {
 452                struct drm_encoder *encoder = priv->encoders[i];
 453                struct omap_dss_device *dssdev =
 454                                        omap_encoder_get_dssdev(encoder);
 455                struct omap_dss_device *output;
 456
 457                output = omapdss_find_output_from_display(dssdev);
 458
 459                /* figure out which crtc's we can connect the encoder to: */
 460                encoder->possible_crtcs = 0;
 461                for (id = 0; id < priv->num_crtcs; id++) {
 462                        struct drm_crtc *crtc = priv->crtcs[id];
 463                        enum omap_channel crtc_channel;
 464
 465                        crtc_channel = omap_crtc_channel(crtc);
 466
 467                        if (output->dispc_channel == crtc_channel) {
 468                                encoder->possible_crtcs |= (1 << id);
 469                                break;
 470                        }
 471                }
 472
 473                omap_dss_put_device(output);
 474        }
 475
 476        DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n",
 477                priv->num_planes, priv->num_crtcs, priv->num_encoders,
 478                priv->num_connectors);
 479
 480        dev->mode_config.min_width = 32;
 481        dev->mode_config.min_height = 32;
 482
 483        /* note: eventually will need some cpu_is_omapXYZ() type stuff here
 484         * to fill in these limits properly on different OMAP generations..
 485         */
 486        dev->mode_config.max_width = 2048;
 487        dev->mode_config.max_height = 2048;
 488
 489        dev->mode_config.funcs = &omap_mode_config_funcs;
 490
 491        drm_mode_config_reset(dev);
 492
 493        return 0;
 494}
 495
 496static void omap_modeset_free(struct drm_device *dev)
 497{
 498        drm_mode_config_cleanup(dev);
 499}
 500
 501/*
 502 * drm ioctl funcs
 503 */
 504
 505
 506static int ioctl_get_param(struct drm_device *dev, void *data,
 507                struct drm_file *file_priv)
 508{
 509        struct omap_drm_private *priv = dev->dev_private;
 510        struct drm_omap_param *args = data;
 511
 512        DBG("%p: param=%llu", dev, args->param);
 513
 514        switch (args->param) {
 515        case OMAP_PARAM_CHIPSET_ID:
 516                args->value = priv->omaprev;
 517                break;
 518        default:
 519                DBG("unknown parameter %lld", args->param);
 520                return -EINVAL;
 521        }
 522
 523        return 0;
 524}
 525
 526static int ioctl_set_param(struct drm_device *dev, void *data,
 527                struct drm_file *file_priv)
 528{
 529        struct drm_omap_param *args = data;
 530
 531        switch (args->param) {
 532        default:
 533                DBG("unknown parameter %lld", args->param);
 534                return -EINVAL;
 535        }
 536
 537        return 0;
 538}
 539
 540#define OMAP_BO_USER_MASK       0x00ffffff      /* flags settable by userspace */
 541
 542static int ioctl_gem_new(struct drm_device *dev, void *data,
 543                struct drm_file *file_priv)
 544{
 545        struct drm_omap_gem_new *args = data;
 546        u32 flags = args->flags & OMAP_BO_USER_MASK;
 547
 548        VERB("%p:%p: size=0x%08x, flags=%08x", dev, file_priv,
 549             args->size.bytes, flags);
 550
 551        return omap_gem_new_handle(dev, file_priv, args->size, flags,
 552                                   &args->handle);
 553}
 554
 555static int ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
 556                struct drm_file *file_priv)
 557{
 558        struct drm_omap_gem_cpu_prep *args = data;
 559        struct drm_gem_object *obj;
 560        int ret;
 561
 562        VERB("%p:%p: handle=%d, op=%x", dev, file_priv, args->handle, args->op);
 563
 564        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 565        if (!obj)
 566                return -ENOENT;
 567
 568        ret = omap_gem_op_sync(obj, args->op);
 569
 570        if (!ret)
 571                ret = omap_gem_op_start(obj, args->op);
 572
 573        drm_gem_object_unreference_unlocked(obj);
 574
 575        return ret;
 576}
 577
 578static int ioctl_gem_cpu_fini(struct drm_device *dev, void *data,
 579                struct drm_file *file_priv)
 580{
 581        struct drm_omap_gem_cpu_fini *args = data;
 582        struct drm_gem_object *obj;
 583        int ret;
 584
 585        VERB("%p:%p: handle=%d", dev, file_priv, args->handle);
 586
 587        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 588        if (!obj)
 589                return -ENOENT;
 590
 591        /* XXX flushy, flushy */
 592        ret = 0;
 593
 594        if (!ret)
 595                ret = omap_gem_op_finish(obj, args->op);
 596
 597        drm_gem_object_unreference_unlocked(obj);
 598
 599        return ret;
 600}
 601
 602static int ioctl_gem_info(struct drm_device *dev, void *data,
 603                struct drm_file *file_priv)
 604{
 605        struct drm_omap_gem_info *args = data;
 606        struct drm_gem_object *obj;
 607        int ret = 0;
 608
 609        VERB("%p:%p: handle=%d", dev, file_priv, args->handle);
 610
 611        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 612        if (!obj)
 613                return -ENOENT;
 614
 615        args->size = omap_gem_mmap_size(obj);
 616        args->offset = omap_gem_mmap_offset(obj);
 617
 618        drm_gem_object_unreference_unlocked(obj);
 619
 620        return ret;
 621}
 622
 623static const struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = {
 624        DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_AUTH),
 625        DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 626        DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_AUTH),
 627        DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, ioctl_gem_cpu_prep, DRM_AUTH),
 628        DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, ioctl_gem_cpu_fini, DRM_AUTH),
 629        DRM_IOCTL_DEF_DRV(OMAP_GEM_INFO, ioctl_gem_info, DRM_AUTH),
 630};
 631
 632/*
 633 * drm driver funcs
 634 */
 635
 636/**
 637 * load - setup chip and create an initial config
 638 * @dev: DRM device
 639 * @flags: startup flags
 640 *
 641 * The driver load routine has to do several things:
 642 *   - initialize the memory manager
 643 *   - allocate initial config memory
 644 *   - setup the DRM framebuffer with the allocated memory
 645 */
 646static int dev_load(struct drm_device *dev, unsigned long flags)
 647{
 648        struct omap_drm_platform_data *pdata = dev->dev->platform_data;
 649        struct omap_drm_private *priv;
 650        unsigned int i;
 651        int ret;
 652
 653        DBG("load: dev=%p", dev);
 654
 655        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 656        if (!priv)
 657                return -ENOMEM;
 658
 659        priv->omaprev = pdata->omaprev;
 660
 661        dev->dev_private = priv;
 662
 663        priv->wq = alloc_ordered_workqueue("omapdrm", 0);
 664        init_waitqueue_head(&priv->commit.wait);
 665        spin_lock_init(&priv->commit.lock);
 666
 667        spin_lock_init(&priv->list_lock);
 668        INIT_LIST_HEAD(&priv->obj_list);
 669
 670        omap_gem_init(dev);
 671
 672        ret = omap_modeset_init(dev);
 673        if (ret) {
 674                dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret);
 675                dev->dev_private = NULL;
 676                kfree(priv);
 677                return ret;
 678        }
 679
 680        /* Initialize vblank handling, start with all CRTCs disabled. */
 681        ret = drm_vblank_init(dev, priv->num_crtcs);
 682        if (ret)
 683                dev_warn(dev->dev, "could not init vblank\n");
 684
 685        for (i = 0; i < priv->num_crtcs; i++)
 686                drm_crtc_vblank_off(priv->crtcs[i]);
 687
 688        priv->fbdev = omap_fbdev_init(dev);
 689
 690        /* store off drm_device for use in pm ops */
 691        dev_set_drvdata(dev->dev, dev);
 692
 693        drm_kms_helper_poll_init(dev);
 694
 695        return 0;
 696}
 697
 698static int dev_unload(struct drm_device *dev)
 699{
 700        struct omap_drm_private *priv = dev->dev_private;
 701
 702        DBG("unload: dev=%p", dev);
 703
 704        drm_kms_helper_poll_fini(dev);
 705
 706        if (priv->fbdev)
 707                omap_fbdev_free(dev);
 708
 709        omap_modeset_free(dev);
 710        omap_gem_deinit(dev);
 711
 712        destroy_workqueue(priv->wq);
 713
 714        drm_vblank_cleanup(dev);
 715        omap_drm_irq_uninstall(dev);
 716
 717        kfree(dev->dev_private);
 718        dev->dev_private = NULL;
 719
 720        dev_set_drvdata(dev->dev, NULL);
 721
 722        return 0;
 723}
 724
 725static int dev_open(struct drm_device *dev, struct drm_file *file)
 726{
 727        file->driver_priv = NULL;
 728
 729        DBG("open: dev=%p, file=%p", dev, file);
 730
 731        return 0;
 732}
 733
 734/**
 735 * lastclose - clean up after all DRM clients have exited
 736 * @dev: DRM device
 737 *
 738 * Take care of cleaning up after all DRM clients have exited.  In the
 739 * mode setting case, we want to restore the kernel's initial mode (just
 740 * in case the last client left us in a bad state).
 741 */
 742static void dev_lastclose(struct drm_device *dev)
 743{
 744        int i;
 745
 746        /* we don't support vga_switcheroo.. so just make sure the fbdev
 747         * mode is active
 748         */
 749        struct omap_drm_private *priv = dev->dev_private;
 750        int ret;
 751
 752        DBG("lastclose: dev=%p", dev);
 753
 754        if (dev->mode_config.rotation_property) {
 755                /* need to restore default rotation state.. not sure
 756                 * if there is a cleaner way to restore properties to
 757                 * default state?  Maybe a flag that properties should
 758                 * automatically be restored to default state on
 759                 * lastclose?
 760                 */
 761                for (i = 0; i < priv->num_crtcs; i++) {
 762                        drm_object_property_set_value(&priv->crtcs[i]->base,
 763                                        dev->mode_config.rotation_property, 0);
 764                }
 765
 766                for (i = 0; i < priv->num_planes; i++) {
 767                        drm_object_property_set_value(&priv->planes[i]->base,
 768                                        dev->mode_config.rotation_property, 0);
 769                }
 770        }
 771
 772        if (priv->fbdev) {
 773                ret = drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
 774                if (ret)
 775                        DBG("failed to restore crtc mode");
 776        }
 777}
 778
 779static const struct vm_operations_struct omap_gem_vm_ops = {
 780        .fault = omap_gem_fault,
 781        .open = drm_gem_vm_open,
 782        .close = drm_gem_vm_close,
 783};
 784
 785static const struct file_operations omapdriver_fops = {
 786        .owner = THIS_MODULE,
 787        .open = drm_open,
 788        .unlocked_ioctl = drm_ioctl,
 789        .release = drm_release,
 790        .mmap = omap_gem_mmap,
 791        .poll = drm_poll,
 792        .read = drm_read,
 793        .llseek = noop_llseek,
 794};
 795
 796static struct drm_driver omap_drm_driver = {
 797        .driver_features = DRIVER_MODESET | DRIVER_GEM  | DRIVER_PRIME |
 798                DRIVER_ATOMIC,
 799        .load = dev_load,
 800        .unload = dev_unload,
 801        .open = dev_open,
 802        .lastclose = dev_lastclose,
 803        .set_busid = drm_platform_set_busid,
 804        .get_vblank_counter = drm_vblank_no_hw_counter,
 805        .enable_vblank = omap_irq_enable_vblank,
 806        .disable_vblank = omap_irq_disable_vblank,
 807#ifdef CONFIG_DEBUG_FS
 808        .debugfs_init = omap_debugfs_init,
 809        .debugfs_cleanup = omap_debugfs_cleanup,
 810#endif
 811        .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 812        .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 813        .gem_prime_export = omap_gem_prime_export,
 814        .gem_prime_import = omap_gem_prime_import,
 815        .gem_free_object = omap_gem_free_object,
 816        .gem_vm_ops = &omap_gem_vm_ops,
 817        .dumb_create = omap_gem_dumb_create,
 818        .dumb_map_offset = omap_gem_dumb_map_offset,
 819        .dumb_destroy = drm_gem_dumb_destroy,
 820        .ioctls = ioctls,
 821        .num_ioctls = DRM_OMAP_NUM_IOCTLS,
 822        .fops = &omapdriver_fops,
 823        .name = DRIVER_NAME,
 824        .desc = DRIVER_DESC,
 825        .date = DRIVER_DATE,
 826        .major = DRIVER_MAJOR,
 827        .minor = DRIVER_MINOR,
 828        .patchlevel = DRIVER_PATCHLEVEL,
 829};
 830
 831static int pdev_probe(struct platform_device *device)
 832{
 833        int r;
 834
 835        if (omapdss_is_initialized() == false)
 836                return -EPROBE_DEFER;
 837
 838        omap_crtc_pre_init();
 839
 840        r = omap_connect_dssdevs();
 841        if (r) {
 842                omap_crtc_pre_uninit();
 843                return r;
 844        }
 845
 846        DBG("%s", device->name);
 847        return drm_platform_init(&omap_drm_driver, device);
 848}
 849
 850static int pdev_remove(struct platform_device *device)
 851{
 852        DBG("");
 853
 854        drm_put_dev(platform_get_drvdata(device));
 855
 856        omap_disconnect_dssdevs();
 857        omap_crtc_pre_uninit();
 858
 859        return 0;
 860}
 861
 862#ifdef CONFIG_PM_SLEEP
 863static int omap_drm_suspend_all_displays(void)
 864{
 865        struct omap_dss_device *dssdev = NULL;
 866
 867        for_each_dss_dev(dssdev) {
 868                if (!dssdev->driver)
 869                        continue;
 870
 871                if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 872                        dssdev->driver->disable(dssdev);
 873                        dssdev->activate_after_resume = true;
 874                } else {
 875                        dssdev->activate_after_resume = false;
 876                }
 877        }
 878
 879        return 0;
 880}
 881
 882static int omap_drm_resume_all_displays(void)
 883{
 884        struct omap_dss_device *dssdev = NULL;
 885
 886        for_each_dss_dev(dssdev) {
 887                if (!dssdev->driver)
 888                        continue;
 889
 890                if (dssdev->activate_after_resume) {
 891                        dssdev->driver->enable(dssdev);
 892                        dssdev->activate_after_resume = false;
 893                }
 894        }
 895
 896        return 0;
 897}
 898
 899static int omap_drm_suspend(struct device *dev)
 900{
 901        struct drm_device *drm_dev = dev_get_drvdata(dev);
 902
 903        drm_kms_helper_poll_disable(drm_dev);
 904
 905        drm_modeset_lock_all(drm_dev);
 906        omap_drm_suspend_all_displays();
 907        drm_modeset_unlock_all(drm_dev);
 908
 909        return 0;
 910}
 911
 912static int omap_drm_resume(struct device *dev)
 913{
 914        struct drm_device *drm_dev = dev_get_drvdata(dev);
 915
 916        drm_modeset_lock_all(drm_dev);
 917        omap_drm_resume_all_displays();
 918        drm_modeset_unlock_all(drm_dev);
 919
 920        drm_kms_helper_poll_enable(drm_dev);
 921
 922        return omap_gem_resume(dev);
 923}
 924#endif
 925
 926static SIMPLE_DEV_PM_OPS(omapdrm_pm_ops, omap_drm_suspend, omap_drm_resume);
 927
 928static struct platform_driver pdev = {
 929        .driver = {
 930                .name = DRIVER_NAME,
 931                .pm = &omapdrm_pm_ops,
 932        },
 933        .probe = pdev_probe,
 934        .remove = pdev_remove,
 935};
 936
 937static struct platform_driver * const drivers[] = {
 938        &omap_dmm_driver,
 939        &pdev,
 940};
 941
 942static int __init omap_drm_init(void)
 943{
 944        DBG("init");
 945
 946        return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
 947}
 948
 949static void __exit omap_drm_fini(void)
 950{
 951        DBG("fini");
 952
 953        platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
 954}
 955
 956/* need late_initcall() so we load after dss_driver's are loaded */
 957late_initcall(omap_drm_init);
 958module_exit(omap_drm_fini);
 959
 960MODULE_AUTHOR("Rob Clark <rob@ti.com>");
 961MODULE_DESCRIPTION("OMAP DRM Display Driver");
 962MODULE_ALIAS("platform:" DRIVER_NAME);
 963MODULE_LICENSE("GPL v2");
 964