linux/drivers/gpu/drm/exynos/exynos_drm_drv.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
   3 * Authors:
   4 *      Inki Dae <inki.dae@samsung.com>
   5 *      Joonyoung Shim <jy0922.shim@samsung.com>
   6 *      Seung-Woo Kim <sw0312.kim@samsung.com>
   7 *
   8 * This program is free software; you can redistribute  it and/or modify it
   9 * under  the terms of  the GNU General  Public License as published by the
  10 * Free Software Foundation;  either version 2 of the  License, or (at your
  11 * option) any later version.
  12 */
  13
  14#include <linux/pm_runtime.h>
  15#include <drm/drmP.h>
  16#include <drm/drm_atomic.h>
  17#include <drm/drm_atomic_helper.h>
  18#include <drm/drm_crtc_helper.h>
  19#include <drm/drm_fb_helper.h>
  20
  21#include <linux/component.h>
  22
  23#include <drm/exynos_drm.h>
  24
  25#include "exynos_drm_drv.h"
  26#include "exynos_drm_fbdev.h"
  27#include "exynos_drm_fb.h"
  28#include "exynos_drm_gem.h"
  29#include "exynos_drm_plane.h"
  30#include "exynos_drm_vidi.h"
  31#include "exynos_drm_g2d.h"
  32#include "exynos_drm_iommu.h"
  33
  34#define DRIVER_NAME     "exynos"
  35#define DRIVER_DESC     "Samsung SoC DRM"
  36#define DRIVER_DATE     "20110530"
  37#define DRIVER_MAJOR    1
  38#define DRIVER_MINOR    0
  39
  40int exynos_atomic_check(struct drm_device *dev,
  41                        struct drm_atomic_state *state)
  42{
  43        int ret;
  44
  45        ret = drm_atomic_helper_check_modeset(dev, state);
  46        if (ret)
  47                return ret;
  48
  49        ret = drm_atomic_normalize_zpos(dev, state);
  50        if (ret)
  51                return ret;
  52
  53        ret = drm_atomic_helper_check_planes(dev, state);
  54        if (ret)
  55                return ret;
  56
  57        return ret;
  58}
  59
  60static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
  61{
  62        struct drm_exynos_file_private *file_priv;
  63        int ret;
  64
  65        file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
  66        if (!file_priv)
  67                return -ENOMEM;
  68
  69        file->driver_priv = file_priv;
  70
  71        ret = exynos_drm_subdrv_open(dev, file);
  72        if (ret)
  73                goto err_file_priv_free;
  74
  75        return ret;
  76
  77err_file_priv_free:
  78        kfree(file_priv);
  79        file->driver_priv = NULL;
  80        return ret;
  81}
  82
  83static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
  84{
  85        exynos_drm_subdrv_close(dev, file);
  86        kfree(file->driver_priv);
  87        file->driver_priv = NULL;
  88}
  89
  90static const struct vm_operations_struct exynos_drm_gem_vm_ops = {
  91        .fault = exynos_drm_gem_fault,
  92        .open = drm_gem_vm_open,
  93        .close = drm_gem_vm_close,
  94};
  95
  96static const struct drm_ioctl_desc exynos_ioctls[] = {
  97        DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
  98                        DRM_AUTH | DRM_RENDER_ALLOW),
  99        DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP, exynos_drm_gem_map_ioctl,
 100                        DRM_AUTH | DRM_RENDER_ALLOW),
 101        DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, exynos_drm_gem_get_ioctl,
 102                        DRM_RENDER_ALLOW),
 103        DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, vidi_connection_ioctl,
 104                        DRM_AUTH),
 105        DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER, exynos_g2d_get_ver_ioctl,
 106                        DRM_AUTH | DRM_RENDER_ALLOW),
 107        DRM_IOCTL_DEF_DRV(EXYNOS_G2D_SET_CMDLIST, exynos_g2d_set_cmdlist_ioctl,
 108                        DRM_AUTH | DRM_RENDER_ALLOW),
 109        DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC, exynos_g2d_exec_ioctl,
 110                        DRM_AUTH | DRM_RENDER_ALLOW),
 111};
 112
 113static const struct file_operations exynos_drm_driver_fops = {
 114        .owner          = THIS_MODULE,
 115        .open           = drm_open,
 116        .mmap           = exynos_drm_gem_mmap,
 117        .poll           = drm_poll,
 118        .read           = drm_read,
 119        .unlocked_ioctl = drm_ioctl,
 120        .compat_ioctl = drm_compat_ioctl,
 121        .release        = drm_release,
 122};
 123
 124static struct drm_driver exynos_drm_driver = {
 125        .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME
 126                                  | DRIVER_ATOMIC | DRIVER_RENDER,
 127        .open                   = exynos_drm_open,
 128        .lastclose              = drm_fb_helper_lastclose,
 129        .postclose              = exynos_drm_postclose,
 130        .gem_free_object_unlocked = exynos_drm_gem_free_object,
 131        .gem_vm_ops             = &exynos_drm_gem_vm_ops,
 132        .dumb_create            = exynos_drm_gem_dumb_create,
 133        .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
 134        .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
 135        .gem_prime_export       = drm_gem_prime_export,
 136        .gem_prime_import       = exynos_drm_gem_prime_import,
 137        .gem_prime_get_sg_table = exynos_drm_gem_prime_get_sg_table,
 138        .gem_prime_import_sg_table      = exynos_drm_gem_prime_import_sg_table,
 139        .gem_prime_vmap         = exynos_drm_gem_prime_vmap,
 140        .gem_prime_vunmap       = exynos_drm_gem_prime_vunmap,
 141        .gem_prime_mmap         = exynos_drm_gem_prime_mmap,
 142        .ioctls                 = exynos_ioctls,
 143        .num_ioctls             = ARRAY_SIZE(exynos_ioctls),
 144        .fops                   = &exynos_drm_driver_fops,
 145        .name   = DRIVER_NAME,
 146        .desc   = DRIVER_DESC,
 147        .date   = DRIVER_DATE,
 148        .major  = DRIVER_MAJOR,
 149        .minor  = DRIVER_MINOR,
 150};
 151
 152#ifdef CONFIG_PM_SLEEP
 153static int exynos_drm_suspend(struct device *dev)
 154{
 155        struct drm_device *drm_dev = dev_get_drvdata(dev);
 156        struct exynos_drm_private *private;
 157
 158        if (pm_runtime_suspended(dev) || !drm_dev)
 159                return 0;
 160
 161        private = drm_dev->dev_private;
 162
 163        drm_kms_helper_poll_disable(drm_dev);
 164        exynos_drm_fbdev_suspend(drm_dev);
 165        private->suspend_state = drm_atomic_helper_suspend(drm_dev);
 166        if (IS_ERR(private->suspend_state)) {
 167                exynos_drm_fbdev_resume(drm_dev);
 168                drm_kms_helper_poll_enable(drm_dev);
 169                return PTR_ERR(private->suspend_state);
 170        }
 171
 172        return 0;
 173}
 174
 175static int exynos_drm_resume(struct device *dev)
 176{
 177        struct drm_device *drm_dev = dev_get_drvdata(dev);
 178        struct exynos_drm_private *private;
 179
 180        if (pm_runtime_suspended(dev) || !drm_dev)
 181                return 0;
 182
 183        private = drm_dev->dev_private;
 184        drm_atomic_helper_resume(drm_dev, private->suspend_state);
 185        exynos_drm_fbdev_resume(drm_dev);
 186        drm_kms_helper_poll_enable(drm_dev);
 187
 188        return 0;
 189}
 190#endif
 191
 192static const struct dev_pm_ops exynos_drm_pm_ops = {
 193        SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_suspend, exynos_drm_resume)
 194};
 195
 196/* forward declaration */
 197static struct platform_driver exynos_drm_platform_driver;
 198
 199struct exynos_drm_driver_info {
 200        struct platform_driver *driver;
 201        unsigned int flags;
 202};
 203
 204#define DRM_COMPONENT_DRIVER    BIT(0)  /* supports component framework */
 205#define DRM_VIRTUAL_DEVICE      BIT(1)  /* create virtual platform device */
 206#define DRM_DMA_DEVICE          BIT(2)  /* can be used for dma allocations */
 207
 208#define DRV_PTR(drv, cond) (IS_ENABLED(cond) ? &drv : NULL)
 209
 210/*
 211 * Connector drivers should not be placed before associated crtc drivers,
 212 * because connector requires pipe number of its crtc during initialization.
 213 */
 214static struct exynos_drm_driver_info exynos_drm_drivers[] = {
 215        {
 216                DRV_PTR(fimd_driver, CONFIG_DRM_EXYNOS_FIMD),
 217                DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
 218        }, {
 219                DRV_PTR(exynos5433_decon_driver, CONFIG_DRM_EXYNOS5433_DECON),
 220                DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
 221        }, {
 222                DRV_PTR(decon_driver, CONFIG_DRM_EXYNOS7_DECON),
 223                DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
 224        }, {
 225                DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER),
 226                DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
 227        }, {
 228                DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC),
 229                DRM_COMPONENT_DRIVER
 230        }, {
 231                DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP),
 232                DRM_COMPONENT_DRIVER
 233        }, {
 234                DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI),
 235                DRM_COMPONENT_DRIVER
 236        }, {
 237                DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI),
 238                DRM_COMPONENT_DRIVER
 239        }, {
 240                DRV_PTR(vidi_driver, CONFIG_DRM_EXYNOS_VIDI),
 241                DRM_COMPONENT_DRIVER | DRM_VIRTUAL_DEVICE
 242        }, {
 243                DRV_PTR(g2d_driver, CONFIG_DRM_EXYNOS_G2D),
 244        }, {
 245                DRV_PTR(fimc_driver, CONFIG_DRM_EXYNOS_FIMC),
 246        }, {
 247                DRV_PTR(rotator_driver, CONFIG_DRM_EXYNOS_ROTATOR),
 248        }, {
 249                DRV_PTR(gsc_driver, CONFIG_DRM_EXYNOS_GSC),
 250        }, {
 251                &exynos_drm_platform_driver,
 252                DRM_VIRTUAL_DEVICE
 253        }
 254};
 255
 256static int compare_dev(struct device *dev, void *data)
 257{
 258        return dev == (struct device *)data;
 259}
 260
 261static struct component_match *exynos_drm_match_add(struct device *dev)
 262{
 263        struct component_match *match = NULL;
 264        int i;
 265
 266        for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
 267                struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
 268                struct device *p = NULL, *d;
 269
 270                if (!info->driver || !(info->flags & DRM_COMPONENT_DRIVER))
 271                        continue;
 272
 273                while ((d = bus_find_device(&platform_bus_type, p,
 274                                            &info->driver->driver,
 275                                            (void *)platform_bus_type.match))) {
 276                        put_device(p);
 277                        component_match_add(dev, &match, compare_dev, d);
 278                        p = d;
 279                }
 280                put_device(p);
 281        }
 282
 283        return match ?: ERR_PTR(-ENODEV);
 284}
 285
 286static struct device *exynos_drm_get_dma_device(void)
 287{
 288        int i;
 289
 290        for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
 291                struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
 292                struct device *dev;
 293
 294                if (!info->driver || !(info->flags & DRM_DMA_DEVICE))
 295                        continue;
 296
 297                while ((dev = bus_find_device(&platform_bus_type, NULL,
 298                                            &info->driver->driver,
 299                                            (void *)platform_bus_type.match))) {
 300                        put_device(dev);
 301                        return dev;
 302                }
 303        }
 304        return NULL;
 305}
 306
 307static int exynos_drm_bind(struct device *dev)
 308{
 309        struct exynos_drm_private *private;
 310        struct drm_encoder *encoder;
 311        struct drm_device *drm;
 312        unsigned int clone_mask;
 313        int cnt, ret;
 314
 315        drm = drm_dev_alloc(&exynos_drm_driver, dev);
 316        if (IS_ERR(drm))
 317                return PTR_ERR(drm);
 318
 319        private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
 320        if (!private) {
 321                ret = -ENOMEM;
 322                goto err_free_drm;
 323        }
 324
 325        init_waitqueue_head(&private->wait);
 326        spin_lock_init(&private->lock);
 327
 328        dev_set_drvdata(dev, drm);
 329        drm->dev_private = (void *)private;
 330
 331        /* the first real CRTC device is used for all dma mapping operations */
 332        private->dma_dev = exynos_drm_get_dma_device();
 333        if (!private->dma_dev) {
 334                DRM_ERROR("no device found for DMA mapping operations.\n");
 335                ret = -ENODEV;
 336                goto err_free_private;
 337        }
 338        DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
 339                 dev_name(private->dma_dev));
 340
 341        /* create common IOMMU mapping for all devices attached to Exynos DRM */
 342        ret = drm_create_iommu_mapping(drm);
 343        if (ret < 0) {
 344                DRM_ERROR("failed to create iommu mapping.\n");
 345                goto err_free_private;
 346        }
 347
 348        drm_mode_config_init(drm);
 349
 350        exynos_drm_mode_config_init(drm);
 351
 352        /* setup possible_clones. */
 353        cnt = 0;
 354        clone_mask = 0;
 355        list_for_each_entry(encoder, &drm->mode_config.encoder_list, head)
 356                clone_mask |= (1 << (cnt++));
 357
 358        list_for_each_entry(encoder, &drm->mode_config.encoder_list, head)
 359                encoder->possible_clones = clone_mask;
 360
 361        /* Try to bind all sub drivers. */
 362        ret = component_bind_all(drm->dev, drm);
 363        if (ret)
 364                goto err_mode_config_cleanup;
 365
 366        ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
 367        if (ret)
 368                goto err_unbind_all;
 369
 370        /* Probe non kms sub drivers and virtual display driver. */
 371        ret = exynos_drm_device_subdrv_probe(drm);
 372        if (ret)
 373                goto err_unbind_all;
 374
 375        drm_mode_config_reset(drm);
 376
 377        /*
 378         * enable drm irq mode.
 379         * - with irq_enabled = true, we can use the vblank feature.
 380         *
 381         * P.S. note that we wouldn't use drm irq handler but
 382         *      just specific driver own one instead because
 383         *      drm framework supports only one irq handler.
 384         */
 385        drm->irq_enabled = true;
 386
 387        /* init kms poll for handling hpd */
 388        drm_kms_helper_poll_init(drm);
 389
 390        ret = exynos_drm_fbdev_init(drm);
 391        if (ret)
 392                goto err_cleanup_poll;
 393
 394        /* register the DRM device */
 395        ret = drm_dev_register(drm, 0);
 396        if (ret < 0)
 397                goto err_cleanup_fbdev;
 398
 399        return 0;
 400
 401err_cleanup_fbdev:
 402        exynos_drm_fbdev_fini(drm);
 403err_cleanup_poll:
 404        drm_kms_helper_poll_fini(drm);
 405        exynos_drm_device_subdrv_remove(drm);
 406err_unbind_all:
 407        component_unbind_all(drm->dev, drm);
 408err_mode_config_cleanup:
 409        drm_mode_config_cleanup(drm);
 410        drm_release_iommu_mapping(drm);
 411err_free_private:
 412        kfree(private);
 413err_free_drm:
 414        drm_dev_unref(drm);
 415
 416        return ret;
 417}
 418
 419static void exynos_drm_unbind(struct device *dev)
 420{
 421        struct drm_device *drm = dev_get_drvdata(dev);
 422
 423        drm_dev_unregister(drm);
 424
 425        exynos_drm_device_subdrv_remove(drm);
 426
 427        exynos_drm_fbdev_fini(drm);
 428        drm_kms_helper_poll_fini(drm);
 429
 430        component_unbind_all(drm->dev, drm);
 431        drm_mode_config_cleanup(drm);
 432        drm_release_iommu_mapping(drm);
 433
 434        kfree(drm->dev_private);
 435        drm->dev_private = NULL;
 436        dev_set_drvdata(dev, NULL);
 437
 438        drm_dev_unref(drm);
 439}
 440
 441static const struct component_master_ops exynos_drm_ops = {
 442        .bind           = exynos_drm_bind,
 443        .unbind         = exynos_drm_unbind,
 444};
 445
 446static int exynos_drm_platform_probe(struct platform_device *pdev)
 447{
 448        struct component_match *match;
 449
 450        pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 451
 452        match = exynos_drm_match_add(&pdev->dev);
 453        if (IS_ERR(match))
 454                return PTR_ERR(match);
 455
 456        return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
 457                                               match);
 458}
 459
 460static int exynos_drm_platform_remove(struct platform_device *pdev)
 461{
 462        component_master_del(&pdev->dev, &exynos_drm_ops);
 463        return 0;
 464}
 465
 466static struct platform_driver exynos_drm_platform_driver = {
 467        .probe  = exynos_drm_platform_probe,
 468        .remove = exynos_drm_platform_remove,
 469        .driver = {
 470                .name   = "exynos-drm",
 471                .pm     = &exynos_drm_pm_ops,
 472        },
 473};
 474
 475static void exynos_drm_unregister_devices(void)
 476{
 477        int i;
 478
 479        for (i = ARRAY_SIZE(exynos_drm_drivers) - 1; i >= 0; --i) {
 480                struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
 481                struct device *dev;
 482
 483                if (!info->driver || !(info->flags & DRM_VIRTUAL_DEVICE))
 484                        continue;
 485
 486                while ((dev = bus_find_device(&platform_bus_type, NULL,
 487                                            &info->driver->driver,
 488                                            (void *)platform_bus_type.match))) {
 489                        put_device(dev);
 490                        platform_device_unregister(to_platform_device(dev));
 491                }
 492        }
 493}
 494
 495static int exynos_drm_register_devices(void)
 496{
 497        struct platform_device *pdev;
 498        int i;
 499
 500        for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
 501                struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
 502
 503                if (!info->driver || !(info->flags & DRM_VIRTUAL_DEVICE))
 504                        continue;
 505
 506                pdev = platform_device_register_simple(
 507                                        info->driver->driver.name, -1, NULL, 0);
 508                if (IS_ERR(pdev))
 509                        goto fail;
 510        }
 511
 512        return 0;
 513fail:
 514        exynos_drm_unregister_devices();
 515        return PTR_ERR(pdev);
 516}
 517
 518static void exynos_drm_unregister_drivers(void)
 519{
 520        int i;
 521
 522        for (i = ARRAY_SIZE(exynos_drm_drivers) - 1; i >= 0; --i) {
 523                struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
 524
 525                if (!info->driver)
 526                        continue;
 527
 528                platform_driver_unregister(info->driver);
 529        }
 530}
 531
 532static int exynos_drm_register_drivers(void)
 533{
 534        int i, ret;
 535
 536        for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
 537                struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
 538
 539                if (!info->driver)
 540                        continue;
 541
 542                ret = platform_driver_register(info->driver);
 543                if (ret)
 544                        goto fail;
 545        }
 546        return 0;
 547fail:
 548        exynos_drm_unregister_drivers();
 549        return ret;
 550}
 551
 552static int exynos_drm_init(void)
 553{
 554        int ret;
 555
 556        ret = exynos_drm_register_devices();
 557        if (ret)
 558                return ret;
 559
 560        ret = exynos_drm_register_drivers();
 561        if (ret)
 562                goto err_unregister_pdevs;
 563
 564        return 0;
 565
 566err_unregister_pdevs:
 567        exynos_drm_unregister_devices();
 568
 569        return ret;
 570}
 571
 572static void exynos_drm_exit(void)
 573{
 574        exynos_drm_unregister_drivers();
 575        exynos_drm_unregister_devices();
 576}
 577
 578module_init(exynos_drm_init);
 579module_exit(exynos_drm_exit);
 580
 581MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
 582MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
 583MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
 584MODULE_DESCRIPTION("Samsung SoC DRM Driver");
 585MODULE_LICENSE("GPL");
 586