linux/drivers/gpu/drm/omapdrm/omap_drv.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
   4 * Author: Rob Clark <rob@ti.com>
   5 */
   6
   7#include <linux/dma-mapping.h>
   8#include <linux/platform_device.h>
   9#include <linux/sort.h>
  10#include <linux/sys_soc.h>
  11
  12#include <drm/drm_atomic.h>
  13#include <drm/drm_atomic_helper.h>
  14#include <drm/drm_drv.h>
  15#include <drm/drm_fb_helper.h>
  16#include <drm/drm_file.h>
  17#include <drm/drm_ioctl.h>
  18#include <drm/drm_panel.h>
  19#include <drm/drm_prime.h>
  20#include <drm/drm_probe_helper.h>
  21#include <drm/drm_vblank.h>
  22
  23#include "omap_dmm_tiler.h"
  24#include "omap_drv.h"
  25
  26#define DRIVER_NAME             MODULE_NAME
  27#define DRIVER_DESC             "OMAP DRM"
  28#define DRIVER_DATE             "20110917"
  29#define DRIVER_MAJOR            1
  30#define DRIVER_MINOR            0
  31#define DRIVER_PATCHLEVEL       0
  32
  33/*
  34 * mode config funcs
  35 */
  36
  37/* Notes about mapping DSS and DRM entities:
  38 *    CRTC:        overlay
  39 *    encoder:     manager.. with some extension to allow one primary CRTC
  40 *                 and zero or more video CRTC's to be mapped to one encoder?
  41 *    connector:   dssdev.. manager can be attached/detached from different
  42 *                 devices
  43 */
  44
  45static void omap_atomic_wait_for_completion(struct drm_device *dev,
  46                                            struct drm_atomic_state *old_state)
  47{
  48        struct drm_crtc_state *new_crtc_state;
  49        struct drm_crtc *crtc;
  50        unsigned int i;
  51        int ret;
  52
  53        for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
  54                if (!new_crtc_state->active)
  55                        continue;
  56
  57                ret = omap_crtc_wait_pending(crtc);
  58
  59                if (!ret)
  60                        dev_warn(dev->dev,
  61                                 "atomic complete timeout (pipe %u)!\n", i);
  62        }
  63}
  64
  65static void omap_atomic_commit_tail(struct drm_atomic_state *old_state)
  66{
  67        struct drm_device *dev = old_state->dev;
  68        struct omap_drm_private *priv = dev->dev_private;
  69
  70        priv->dispc_ops->runtime_get(priv->dispc);
  71
  72        /* Apply the atomic update. */
  73        drm_atomic_helper_commit_modeset_disables(dev, old_state);
  74
  75        if (priv->omaprev != 0x3430) {
  76                /* With the current dss dispc implementation we have to enable
  77                 * the new modeset before we can commit planes. The dispc ovl
  78                 * configuration relies on the video mode configuration been
  79                 * written into the HW when the ovl configuration is
  80                 * calculated.
  81                 *
  82                 * This approach is not ideal because after a mode change the
  83                 * plane update is executed only after the first vblank
  84                 * interrupt. The dispc implementation should be fixed so that
  85                 * it is able use uncommitted drm state information.
  86                 */
  87                drm_atomic_helper_commit_modeset_enables(dev, old_state);
  88                omap_atomic_wait_for_completion(dev, old_state);
  89
  90                drm_atomic_helper_commit_planes(dev, old_state, 0);
  91
  92                drm_atomic_helper_commit_hw_done(old_state);
  93        } else {
  94                /*
  95                 * OMAP3 DSS seems to have issues with the work-around above,
  96                 * resulting in endless sync losts if a crtc is enabled without
  97                 * a plane. For now, skip the WA for OMAP3.
  98                 */
  99                drm_atomic_helper_commit_planes(dev, old_state, 0);
 100
 101                drm_atomic_helper_commit_modeset_enables(dev, old_state);
 102
 103                drm_atomic_helper_commit_hw_done(old_state);
 104        }
 105
 106        /*
 107         * Wait for completion of the page flips to ensure that old buffers
 108         * can't be touched by the hardware anymore before cleaning up planes.
 109         */
 110        omap_atomic_wait_for_completion(dev, old_state);
 111
 112        drm_atomic_helper_cleanup_planes(dev, old_state);
 113
 114        priv->dispc_ops->runtime_put(priv->dispc);
 115}
 116
 117static const struct drm_mode_config_helper_funcs omap_mode_config_helper_funcs = {
 118        .atomic_commit_tail = omap_atomic_commit_tail,
 119};
 120
 121static const struct drm_mode_config_funcs omap_mode_config_funcs = {
 122        .fb_create = omap_framebuffer_create,
 123        .output_poll_changed = drm_fb_helper_output_poll_changed,
 124        .atomic_check = drm_atomic_helper_check,
 125        .atomic_commit = drm_atomic_helper_commit,
 126};
 127
 128static void omap_disconnect_pipelines(struct drm_device *ddev)
 129{
 130        struct omap_drm_private *priv = ddev->dev_private;
 131        unsigned int i;
 132
 133        for (i = 0; i < priv->num_pipes; i++) {
 134                struct omap_drm_pipeline *pipe = &priv->pipes[i];
 135
 136                if (pipe->output->panel)
 137                        drm_panel_detach(pipe->output->panel);
 138
 139                omapdss_device_disconnect(NULL, pipe->output);
 140
 141                omapdss_device_put(pipe->output);
 142                pipe->output = NULL;
 143        }
 144
 145        memset(&priv->channels, 0, sizeof(priv->channels));
 146
 147        priv->num_pipes = 0;
 148}
 149
 150static int omap_connect_pipelines(struct drm_device *ddev)
 151{
 152        struct omap_drm_private *priv = ddev->dev_private;
 153        struct omap_dss_device *output = NULL;
 154        int r;
 155
 156        for_each_dss_output(output) {
 157                r = omapdss_device_connect(priv->dss, NULL, output);
 158                if (r == -EPROBE_DEFER) {
 159                        omapdss_device_put(output);
 160                        return r;
 161                } else if (r) {
 162                        dev_warn(output->dev, "could not connect output %s\n",
 163                                 output->name);
 164                } else {
 165                        struct omap_drm_pipeline *pipe;
 166
 167                        pipe = &priv->pipes[priv->num_pipes++];
 168                        pipe->output = omapdss_device_get(output);
 169
 170                        if (priv->num_pipes == ARRAY_SIZE(priv->pipes)) {
 171                                /* To balance the 'for_each_dss_output' loop */
 172                                omapdss_device_put(output);
 173                                break;
 174                        }
 175                }
 176        }
 177
 178        return 0;
 179}
 180
 181static int omap_compare_pipelines(const void *a, const void *b)
 182{
 183        const struct omap_drm_pipeline *pipe1 = a;
 184        const struct omap_drm_pipeline *pipe2 = b;
 185
 186        if (pipe1->alias_id > pipe2->alias_id)
 187                return 1;
 188        else if (pipe1->alias_id < pipe2->alias_id)
 189                return -1;
 190        return 0;
 191}
 192
 193static int omap_modeset_init_properties(struct drm_device *dev)
 194{
 195        struct omap_drm_private *priv = dev->dev_private;
 196        unsigned int num_planes = priv->dispc_ops->get_num_ovls(priv->dispc);
 197
 198        priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0,
 199                                                      num_planes - 1);
 200        if (!priv->zorder_prop)
 201                return -ENOMEM;
 202
 203        return 0;
 204}
 205
 206static int omap_display_id(struct omap_dss_device *output)
 207{
 208        struct device_node *node = NULL;
 209
 210        if (output->next) {
 211                struct omap_dss_device *display;
 212
 213                display = omapdss_display_get(output);
 214                node = display->dev->of_node;
 215                omapdss_device_put(display);
 216        } else if (output->bridge) {
 217                struct drm_bridge *bridge = output->bridge;
 218
 219                while (bridge->next)
 220                        bridge = bridge->next;
 221
 222                node = bridge->of_node;
 223        } else if (output->panel) {
 224                node = output->panel->dev->of_node;
 225        }
 226
 227        return node ? of_alias_get_id(node, "display") : -ENODEV;
 228}
 229
 230static int omap_modeset_init(struct drm_device *dev)
 231{
 232        struct omap_drm_private *priv = dev->dev_private;
 233        int num_ovls = priv->dispc_ops->get_num_ovls(priv->dispc);
 234        int num_mgrs = priv->dispc_ops->get_num_mgrs(priv->dispc);
 235        unsigned int i;
 236        int ret;
 237        u32 plane_crtc_mask;
 238
 239        if (!omapdss_stack_is_ready())
 240                return -EPROBE_DEFER;
 241
 242        drm_mode_config_init(dev);
 243
 244        ret = omap_modeset_init_properties(dev);
 245        if (ret < 0)
 246                return ret;
 247
 248        /*
 249         * This function creates exactly one connector, encoder, crtc,
 250         * and primary plane per each connected dss-device. Each
 251         * connector->encoder->crtc chain is expected to be separate
 252         * and each crtc is connect to a single dss-channel. If the
 253         * configuration does not match the expectations or exceeds
 254         * the available resources, the configuration is rejected.
 255         */
 256        ret = omap_connect_pipelines(dev);
 257        if (ret < 0)
 258                return ret;
 259
 260        if (priv->num_pipes > num_mgrs || priv->num_pipes > num_ovls) {
 261                dev_err(dev->dev, "%s(): Too many connected displays\n",
 262                        __func__);
 263                return -EINVAL;
 264        }
 265
 266        /* Create all planes first. They can all be put to any CRTC. */
 267        plane_crtc_mask = (1 << priv->num_pipes) - 1;
 268
 269        for (i = 0; i < num_ovls; i++) {
 270                enum drm_plane_type type = i < priv->num_pipes
 271                                         ? DRM_PLANE_TYPE_PRIMARY
 272                                         : DRM_PLANE_TYPE_OVERLAY;
 273                struct drm_plane *plane;
 274
 275                if (WARN_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)))
 276                        return -EINVAL;
 277
 278                plane = omap_plane_init(dev, i, type, plane_crtc_mask);
 279                if (IS_ERR(plane))
 280                        return PTR_ERR(plane);
 281
 282                priv->planes[priv->num_planes++] = plane;
 283        }
 284
 285        /*
 286         * Create the encoders, attach the bridges and get the pipeline alias
 287         * IDs.
 288         */
 289        for (i = 0; i < priv->num_pipes; i++) {
 290                struct omap_drm_pipeline *pipe = &priv->pipes[i];
 291                int id;
 292
 293                pipe->encoder = omap_encoder_init(dev, pipe->output);
 294                if (!pipe->encoder)
 295                        return -ENOMEM;
 296
 297                if (pipe->output->bridge) {
 298                        ret = drm_bridge_attach(pipe->encoder,
 299                                                pipe->output->bridge, NULL);
 300                        if (ret < 0)
 301                                return ret;
 302                }
 303
 304                id = omap_display_id(pipe->output);
 305                pipe->alias_id = id >= 0 ? id : i;
 306        }
 307
 308        /* Sort the pipelines by DT aliases. */
 309        sort(priv->pipes, priv->num_pipes, sizeof(priv->pipes[0]),
 310             omap_compare_pipelines, NULL);
 311
 312        /*
 313         * Populate the pipeline lookup table by DISPC channel. Only one display
 314         * is allowed per channel.
 315         */
 316        for (i = 0; i < priv->num_pipes; ++i) {
 317                struct omap_drm_pipeline *pipe = &priv->pipes[i];
 318                enum omap_channel channel = pipe->output->dispc_channel;
 319
 320                if (WARN_ON(priv->channels[channel] != NULL))
 321                        return -EINVAL;
 322
 323                priv->channels[channel] = pipe;
 324        }
 325
 326        /* Create the connectors and CRTCs. */
 327        for (i = 0; i < priv->num_pipes; i++) {
 328                struct omap_drm_pipeline *pipe = &priv->pipes[i];
 329                struct drm_encoder *encoder = pipe->encoder;
 330                struct drm_crtc *crtc;
 331
 332                if (!pipe->output->bridge) {
 333                        pipe->connector = omap_connector_init(dev, pipe->output,
 334                                                              encoder);
 335                        if (!pipe->connector)
 336                                return -ENOMEM;
 337
 338                        drm_connector_attach_encoder(pipe->connector, encoder);
 339
 340                        if (pipe->output->panel) {
 341                                ret = drm_panel_attach(pipe->output->panel,
 342                                                       pipe->connector);
 343                                if (ret < 0)
 344                                        return ret;
 345                        }
 346                }
 347
 348                crtc = omap_crtc_init(dev, pipe, priv->planes[i]);
 349                if (IS_ERR(crtc))
 350                        return PTR_ERR(crtc);
 351
 352                encoder->possible_crtcs = 1 << i;
 353                pipe->crtc = crtc;
 354        }
 355
 356        DBG("registered %u planes, %u crtcs/encoders/connectors\n",
 357            priv->num_planes, priv->num_pipes);
 358
 359        dev->mode_config.min_width = 8;
 360        dev->mode_config.min_height = 2;
 361
 362        /*
 363         * Note: these values are used for multiple independent things:
 364         * connector mode filtering, buffer sizes, crtc sizes...
 365         * Use big enough values here to cover all use cases, and do more
 366         * specific checking in the respective code paths.
 367         */
 368        dev->mode_config.max_width = 8192;
 369        dev->mode_config.max_height = 8192;
 370
 371        /* We want the zpos to be normalized */
 372        dev->mode_config.normalize_zpos = true;
 373
 374        dev->mode_config.funcs = &omap_mode_config_funcs;
 375        dev->mode_config.helper_private = &omap_mode_config_helper_funcs;
 376
 377        drm_mode_config_reset(dev);
 378
 379        omap_drm_irq_install(dev);
 380
 381        return 0;
 382}
 383
 384/*
 385 * Enable the HPD in external components if supported
 386 */
 387static void omap_modeset_enable_external_hpd(struct drm_device *ddev)
 388{
 389        struct omap_drm_private *priv = ddev->dev_private;
 390        unsigned int i;
 391
 392        for (i = 0; i < priv->num_pipes; i++) {
 393                if (priv->pipes[i].connector)
 394                        omap_connector_enable_hpd(priv->pipes[i].connector);
 395        }
 396}
 397
 398/*
 399 * Disable the HPD in external components if supported
 400 */
 401static void omap_modeset_disable_external_hpd(struct drm_device *ddev)
 402{
 403        struct omap_drm_private *priv = ddev->dev_private;
 404        unsigned int i;
 405
 406        for (i = 0; i < priv->num_pipes; i++) {
 407                if (priv->pipes[i].connector)
 408                        omap_connector_disable_hpd(priv->pipes[i].connector);
 409        }
 410}
 411
 412/*
 413 * drm ioctl funcs
 414 */
 415
 416
 417static int ioctl_get_param(struct drm_device *dev, void *data,
 418                struct drm_file *file_priv)
 419{
 420        struct omap_drm_private *priv = dev->dev_private;
 421        struct drm_omap_param *args = data;
 422
 423        DBG("%p: param=%llu", dev, args->param);
 424
 425        switch (args->param) {
 426        case OMAP_PARAM_CHIPSET_ID:
 427                args->value = priv->omaprev;
 428                break;
 429        default:
 430                DBG("unknown parameter %lld", args->param);
 431                return -EINVAL;
 432        }
 433
 434        return 0;
 435}
 436
 437#define OMAP_BO_USER_MASK       0x00ffffff      /* flags settable by userspace */
 438
 439static int ioctl_gem_new(struct drm_device *dev, void *data,
 440                struct drm_file *file_priv)
 441{
 442        struct drm_omap_gem_new *args = data;
 443        u32 flags = args->flags & OMAP_BO_USER_MASK;
 444
 445        VERB("%p:%p: size=0x%08x, flags=%08x", dev, file_priv,
 446             args->size.bytes, flags);
 447
 448        return omap_gem_new_handle(dev, file_priv, args->size, flags,
 449                                   &args->handle);
 450}
 451
 452static int ioctl_gem_info(struct drm_device *dev, void *data,
 453                struct drm_file *file_priv)
 454{
 455        struct drm_omap_gem_info *args = data;
 456        struct drm_gem_object *obj;
 457        int ret = 0;
 458
 459        VERB("%p:%p: handle=%d", dev, file_priv, args->handle);
 460
 461        obj = drm_gem_object_lookup(file_priv, args->handle);
 462        if (!obj)
 463                return -ENOENT;
 464
 465        args->size = omap_gem_mmap_size(obj);
 466        args->offset = omap_gem_mmap_offset(obj);
 467
 468        drm_gem_object_put_unlocked(obj);
 469
 470        return ret;
 471}
 472
 473static const struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = {
 474        DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param,
 475                          DRM_RENDER_ALLOW),
 476        DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, drm_invalid_op,
 477                          DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
 478        DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new,
 479                          DRM_RENDER_ALLOW),
 480        /* Deprecated, to be removed. */
 481        DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, drm_noop,
 482                          DRM_RENDER_ALLOW),
 483        /* Deprecated, to be removed. */
 484        DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, drm_noop,
 485                          DRM_RENDER_ALLOW),
 486        DRM_IOCTL_DEF_DRV(OMAP_GEM_INFO, ioctl_gem_info,
 487                          DRM_RENDER_ALLOW),
 488};
 489
 490/*
 491 * drm driver funcs
 492 */
 493
 494static int dev_open(struct drm_device *dev, struct drm_file *file)
 495{
 496        file->driver_priv = NULL;
 497
 498        DBG("open: dev=%p, file=%p", dev, file);
 499
 500        return 0;
 501}
 502
 503static const struct vm_operations_struct omap_gem_vm_ops = {
 504        .fault = omap_gem_fault,
 505        .open = drm_gem_vm_open,
 506        .close = drm_gem_vm_close,
 507};
 508
 509static const struct file_operations omapdriver_fops = {
 510        .owner = THIS_MODULE,
 511        .open = drm_open,
 512        .unlocked_ioctl = drm_ioctl,
 513        .compat_ioctl = drm_compat_ioctl,
 514        .release = drm_release,
 515        .mmap = omap_gem_mmap,
 516        .poll = drm_poll,
 517        .read = drm_read,
 518        .llseek = noop_llseek,
 519};
 520
 521static struct drm_driver omap_drm_driver = {
 522        .driver_features = DRIVER_MODESET | DRIVER_GEM  |
 523                DRIVER_ATOMIC | DRIVER_RENDER,
 524        .open = dev_open,
 525        .lastclose = drm_fb_helper_lastclose,
 526#ifdef CONFIG_DEBUG_FS
 527        .debugfs_init = omap_debugfs_init,
 528#endif
 529        .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 530        .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 531        .gem_prime_export = omap_gem_prime_export,
 532        .gem_prime_import = omap_gem_prime_import,
 533        .gem_free_object_unlocked = omap_gem_free_object,
 534        .gem_vm_ops = &omap_gem_vm_ops,
 535        .dumb_create = omap_gem_dumb_create,
 536        .dumb_map_offset = omap_gem_dumb_map_offset,
 537        .ioctls = ioctls,
 538        .num_ioctls = DRM_OMAP_NUM_IOCTLS,
 539        .fops = &omapdriver_fops,
 540        .name = DRIVER_NAME,
 541        .desc = DRIVER_DESC,
 542        .date = DRIVER_DATE,
 543        .major = DRIVER_MAJOR,
 544        .minor = DRIVER_MINOR,
 545        .patchlevel = DRIVER_PATCHLEVEL,
 546};
 547
 548static const struct soc_device_attribute omapdrm_soc_devices[] = {
 549        { .family = "OMAP3", .data = (void *)0x3430 },
 550        { .family = "OMAP4", .data = (void *)0x4430 },
 551        { .family = "OMAP5", .data = (void *)0x5430 },
 552        { .family = "DRA7",  .data = (void *)0x0752 },
 553        { /* sentinel */ }
 554};
 555
 556static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
 557{
 558        const struct soc_device_attribute *soc;
 559        struct drm_device *ddev;
 560        unsigned int i;
 561        int ret;
 562
 563        DBG("%s", dev_name(dev));
 564
 565        /* Allocate and initialize the DRM device. */
 566        ddev = drm_dev_alloc(&omap_drm_driver, dev);
 567        if (IS_ERR(ddev))
 568                return PTR_ERR(ddev);
 569
 570        priv->ddev = ddev;
 571        ddev->dev_private = priv;
 572
 573        priv->dev = dev;
 574        priv->dss = omapdss_get_dss();
 575        priv->dispc = dispc_get_dispc(priv->dss);
 576        priv->dispc_ops = dispc_get_ops(priv->dss);
 577
 578        omap_crtc_pre_init(priv);
 579
 580        soc = soc_device_match(omapdrm_soc_devices);
 581        priv->omaprev = soc ? (unsigned int)soc->data : 0;
 582        priv->wq = alloc_ordered_workqueue("omapdrm", 0);
 583
 584        mutex_init(&priv->list_lock);
 585        INIT_LIST_HEAD(&priv->obj_list);
 586
 587        /* Get memory bandwidth limits */
 588        if (priv->dispc_ops->get_memory_bandwidth_limit)
 589                priv->max_bandwidth =
 590                        priv->dispc_ops->get_memory_bandwidth_limit(priv->dispc);
 591
 592        omap_gem_init(ddev);
 593
 594        ret = omap_modeset_init(ddev);
 595        if (ret) {
 596                dev_err(priv->dev, "omap_modeset_init failed: ret=%d\n", ret);
 597                goto err_gem_deinit;
 598        }
 599
 600        /* Initialize vblank handling, start with all CRTCs disabled. */
 601        ret = drm_vblank_init(ddev, priv->num_pipes);
 602        if (ret) {
 603                dev_err(priv->dev, "could not init vblank\n");
 604                goto err_cleanup_modeset;
 605        }
 606
 607        for (i = 0; i < priv->num_pipes; i++)
 608                drm_crtc_vblank_off(priv->pipes[i].crtc);
 609
 610        omap_fbdev_init(ddev);
 611
 612        drm_kms_helper_poll_init(ddev);
 613        omap_modeset_enable_external_hpd(ddev);
 614
 615        /*
 616         * Register the DRM device with the core and the connectors with
 617         * sysfs.
 618         */
 619        ret = drm_dev_register(ddev, 0);
 620        if (ret)
 621                goto err_cleanup_helpers;
 622
 623        return 0;
 624
 625err_cleanup_helpers:
 626        omap_modeset_disable_external_hpd(ddev);
 627        drm_kms_helper_poll_fini(ddev);
 628
 629        omap_fbdev_fini(ddev);
 630err_cleanup_modeset:
 631        drm_mode_config_cleanup(ddev);
 632        omap_drm_irq_uninstall(ddev);
 633err_gem_deinit:
 634        omap_gem_deinit(ddev);
 635        destroy_workqueue(priv->wq);
 636        omap_disconnect_pipelines(ddev);
 637        omap_crtc_pre_uninit(priv);
 638        drm_dev_put(ddev);
 639        return ret;
 640}
 641
 642static void omapdrm_cleanup(struct omap_drm_private *priv)
 643{
 644        struct drm_device *ddev = priv->ddev;
 645
 646        DBG("");
 647
 648        drm_dev_unregister(ddev);
 649
 650        omap_modeset_disable_external_hpd(ddev);
 651        drm_kms_helper_poll_fini(ddev);
 652
 653        omap_fbdev_fini(ddev);
 654
 655        drm_atomic_helper_shutdown(ddev);
 656
 657        drm_mode_config_cleanup(ddev);
 658
 659        omap_drm_irq_uninstall(ddev);
 660        omap_gem_deinit(ddev);
 661
 662        destroy_workqueue(priv->wq);
 663
 664        omap_disconnect_pipelines(ddev);
 665        omap_crtc_pre_uninit(priv);
 666
 667        drm_dev_put(ddev);
 668}
 669
 670static int pdev_probe(struct platform_device *pdev)
 671{
 672        struct omap_drm_private *priv;
 673        int ret;
 674
 675        if (omapdss_is_initialized() == false)
 676                return -EPROBE_DEFER;
 677
 678        ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
 679        if (ret) {
 680                dev_err(&pdev->dev, "Failed to set the DMA mask\n");
 681                return ret;
 682        }
 683
 684        /* Allocate and initialize the driver private structure. */
 685        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 686        if (!priv)
 687                return -ENOMEM;
 688
 689        platform_set_drvdata(pdev, priv);
 690
 691        ret = omapdrm_init(priv, &pdev->dev);
 692        if (ret < 0)
 693                kfree(priv);
 694
 695        return ret;
 696}
 697
 698static int pdev_remove(struct platform_device *pdev)
 699{
 700        struct omap_drm_private *priv = platform_get_drvdata(pdev);
 701
 702        omapdrm_cleanup(priv);
 703        kfree(priv);
 704
 705        return 0;
 706}
 707
 708#ifdef CONFIG_PM_SLEEP
 709static int omap_drm_suspend(struct device *dev)
 710{
 711        struct omap_drm_private *priv = dev_get_drvdata(dev);
 712        struct drm_device *drm_dev = priv->ddev;
 713
 714        return drm_mode_config_helper_suspend(drm_dev);
 715}
 716
 717static int omap_drm_resume(struct device *dev)
 718{
 719        struct omap_drm_private *priv = dev_get_drvdata(dev);
 720        struct drm_device *drm_dev = priv->ddev;
 721
 722        drm_mode_config_helper_resume(drm_dev);
 723
 724        return omap_gem_resume(drm_dev);
 725}
 726#endif
 727
 728static SIMPLE_DEV_PM_OPS(omapdrm_pm_ops, omap_drm_suspend, omap_drm_resume);
 729
 730static struct platform_driver pdev = {
 731        .driver = {
 732                .name = "omapdrm",
 733                .pm = &omapdrm_pm_ops,
 734        },
 735        .probe = pdev_probe,
 736        .remove = pdev_remove,
 737};
 738
 739static struct platform_driver * const drivers[] = {
 740        &omap_dmm_driver,
 741        &pdev,
 742};
 743
 744static int __init omap_drm_init(void)
 745{
 746        DBG("init");
 747
 748        return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
 749}
 750
 751static void __exit omap_drm_fini(void)
 752{
 753        DBG("fini");
 754
 755        platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
 756}
 757
 758/* need late_initcall() so we load after dss_driver's are loaded */
 759late_initcall(omap_drm_init);
 760module_exit(omap_drm_fini);
 761
 762MODULE_AUTHOR("Rob Clark <rob@ti.com>");
 763MODULE_DESCRIPTION("OMAP DRM Display Driver");
 764MODULE_ALIAS("platform:" DRIVER_NAME);
 765MODULE_LICENSE("GPL v2");
 766