linux/drivers/gpu/drm/exynos/exynos_drm_drv.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
   4 * Authors:
   5 *      Inki Dae <inki.dae@samsung.com>
   6 *      Joonyoung Shim <jy0922.shim@samsung.com>
   7 *      Seung-Woo Kim <sw0312.kim@samsung.com>
   8 */
   9
  10#include <linux/component.h>
  11#include <linux/dma-mapping.h>
  12#include <linux/platform_device.h>
  13#include <linux/pm_runtime.h>
  14#include <linux/uaccess.h>
  15
  16#include <drm/drm_atomic.h>
  17#include <drm/drm_atomic_helper.h>
  18#include <drm/drm_drv.h>
  19#include <drm/drm_fb_helper.h>
  20#include <drm/drm_file.h>
  21#include <drm/drm_fourcc.h>
  22#include <drm/drm_ioctl.h>
  23#include <drm/drm_probe_helper.h>
  24#include <drm/drm_vblank.h>
  25#include <drm/exynos_drm.h>
  26
  27#include "exynos_drm_drv.h"
  28#include "exynos_drm_fb.h"
  29#include "exynos_drm_fbdev.h"
  30#include "exynos_drm_g2d.h"
  31#include "exynos_drm_gem.h"
  32#include "exynos_drm_ipp.h"
  33#include "exynos_drm_plane.h"
  34#include "exynos_drm_vidi.h"
  35
  36#define DRIVER_NAME     "exynos"
  37#define DRIVER_DESC     "Samsung SoC DRM"
  38#define DRIVER_DATE     "20180330"
  39
  40/*
  41 * Interface history:
  42 *
  43 * 1.0 - Original version
  44 * 1.1 - Upgrade IPP driver to version 2.0
  45 */
  46#define DRIVER_MAJOR    1
  47#define DRIVER_MINOR    1
  48
  49static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
  50{
  51        struct drm_exynos_file_private *file_priv;
  52        int ret;
  53
  54        file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
  55        if (!file_priv)
  56                return -ENOMEM;
  57
  58        file->driver_priv = file_priv;
  59        ret = g2d_open(dev, file);
  60        if (ret)
  61                goto err_file_priv_free;
  62
  63        return ret;
  64
  65err_file_priv_free:
  66        kfree(file_priv);
  67        file->driver_priv = NULL;
  68        return ret;
  69}
  70
  71static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
  72{
  73        g2d_close(dev, file);
  74        kfree(file->driver_priv);
  75        file->driver_priv = NULL;
  76}
  77
  78static const struct drm_ioctl_desc exynos_ioctls[] = {
  79        DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
  80                        DRM_RENDER_ALLOW),
  81        DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP, exynos_drm_gem_map_ioctl,
  82                        DRM_RENDER_ALLOW),
  83        DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, exynos_drm_gem_get_ioctl,
  84                        DRM_RENDER_ALLOW),
  85        DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, vidi_connection_ioctl,
  86                        DRM_AUTH),
  87        DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER, exynos_g2d_get_ver_ioctl,
  88                        DRM_RENDER_ALLOW),
  89        DRM_IOCTL_DEF_DRV(EXYNOS_G2D_SET_CMDLIST, exynos_g2d_set_cmdlist_ioctl,
  90                        DRM_RENDER_ALLOW),
  91        DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC, exynos_g2d_exec_ioctl,
  92                        DRM_RENDER_ALLOW),
  93        DRM_IOCTL_DEF_DRV(EXYNOS_IPP_GET_RESOURCES,
  94                        exynos_drm_ipp_get_res_ioctl,
  95                        DRM_RENDER_ALLOW),
  96        DRM_IOCTL_DEF_DRV(EXYNOS_IPP_GET_CAPS, exynos_drm_ipp_get_caps_ioctl,
  97                        DRM_RENDER_ALLOW),
  98        DRM_IOCTL_DEF_DRV(EXYNOS_IPP_GET_LIMITS,
  99                        exynos_drm_ipp_get_limits_ioctl,
 100                        DRM_RENDER_ALLOW),
 101        DRM_IOCTL_DEF_DRV(EXYNOS_IPP_COMMIT, exynos_drm_ipp_commit_ioctl,
 102                        DRM_RENDER_ALLOW),
 103};
 104
 105static const struct file_operations exynos_drm_driver_fops = {
 106        .owner          = THIS_MODULE,
 107        .open           = drm_open,
 108        .mmap           = exynos_drm_gem_mmap,
 109        .poll           = drm_poll,
 110        .read           = drm_read,
 111        .unlocked_ioctl = drm_ioctl,
 112        .compat_ioctl = drm_compat_ioctl,
 113        .release        = drm_release,
 114};
 115
 116static const struct drm_driver exynos_drm_driver = {
 117        .driver_features        = DRIVER_MODESET | DRIVER_GEM
 118                                  | DRIVER_ATOMIC | DRIVER_RENDER,
 119        .open                   = exynos_drm_open,
 120        .lastclose              = drm_fb_helper_lastclose,
 121        .postclose              = exynos_drm_postclose,
 122        .dumb_create            = exynos_drm_gem_dumb_create,
 123        .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
 124        .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
 125        .gem_prime_import       = exynos_drm_gem_prime_import,
 126        .gem_prime_import_sg_table      = exynos_drm_gem_prime_import_sg_table,
 127        .gem_prime_mmap         = exynos_drm_gem_prime_mmap,
 128        .ioctls                 = exynos_ioctls,
 129        .num_ioctls             = ARRAY_SIZE(exynos_ioctls),
 130        .fops                   = &exynos_drm_driver_fops,
 131        .name   = DRIVER_NAME,
 132        .desc   = DRIVER_DESC,
 133        .date   = DRIVER_DATE,
 134        .major  = DRIVER_MAJOR,
 135        .minor  = DRIVER_MINOR,
 136};
 137
 138static int exynos_drm_suspend(struct device *dev)
 139{
 140        struct drm_device *drm_dev = dev_get_drvdata(dev);
 141
 142        return  drm_mode_config_helper_suspend(drm_dev);
 143}
 144
 145static void exynos_drm_resume(struct device *dev)
 146{
 147        struct drm_device *drm_dev = dev_get_drvdata(dev);
 148
 149        drm_mode_config_helper_resume(drm_dev);
 150}
 151
 152static const struct dev_pm_ops exynos_drm_pm_ops = {
 153        .prepare = exynos_drm_suspend,
 154        .complete = exynos_drm_resume,
 155};
 156
 157/* forward declaration */
 158static struct platform_driver exynos_drm_platform_driver;
 159
 160struct exynos_drm_driver_info {
 161        struct platform_driver *driver;
 162        unsigned int flags;
 163};
 164
 165#define DRM_COMPONENT_DRIVER    BIT(0)  /* supports component framework */
 166#define DRM_VIRTUAL_DEVICE      BIT(1)  /* create virtual platform device */
 167#define DRM_FIMC_DEVICE         BIT(2)  /* devices shared with V4L2 subsystem */
 168
 169#define DRV_PTR(drv, cond) (IS_ENABLED(cond) ? &drv : NULL)
 170
 171/*
 172 * Connector drivers should not be placed before associated crtc drivers,
 173 * because connector requires pipe number of its crtc during initialization.
 174 */
 175static struct exynos_drm_driver_info exynos_drm_drivers[] = {
 176        {
 177                DRV_PTR(fimd_driver, CONFIG_DRM_EXYNOS_FIMD),
 178                DRM_COMPONENT_DRIVER
 179        }, {
 180                DRV_PTR(exynos5433_decon_driver, CONFIG_DRM_EXYNOS5433_DECON),
 181                DRM_COMPONENT_DRIVER
 182        }, {
 183                DRV_PTR(decon_driver, CONFIG_DRM_EXYNOS7_DECON),
 184                DRM_COMPONENT_DRIVER
 185        }, {
 186                DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER),
 187                DRM_COMPONENT_DRIVER
 188        }, {
 189                DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC),
 190                DRM_COMPONENT_DRIVER
 191        }, {
 192                DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP),
 193                DRM_COMPONENT_DRIVER
 194        }, {
 195                DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI),
 196                DRM_COMPONENT_DRIVER
 197        }, {
 198                DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI),
 199                DRM_COMPONENT_DRIVER
 200        }, {
 201                DRV_PTR(vidi_driver, CONFIG_DRM_EXYNOS_VIDI),
 202                DRM_COMPONENT_DRIVER | DRM_VIRTUAL_DEVICE
 203        }, {
 204                DRV_PTR(g2d_driver, CONFIG_DRM_EXYNOS_G2D),
 205                DRM_COMPONENT_DRIVER
 206        }, {
 207                DRV_PTR(fimc_driver, CONFIG_DRM_EXYNOS_FIMC),
 208                DRM_COMPONENT_DRIVER | DRM_FIMC_DEVICE,
 209        }, {
 210                DRV_PTR(rotator_driver, CONFIG_DRM_EXYNOS_ROTATOR),
 211                DRM_COMPONENT_DRIVER
 212        }, {
 213                DRV_PTR(scaler_driver, CONFIG_DRM_EXYNOS_SCALER),
 214                DRM_COMPONENT_DRIVER
 215        }, {
 216                DRV_PTR(gsc_driver, CONFIG_DRM_EXYNOS_GSC),
 217                DRM_COMPONENT_DRIVER
 218        }, {
 219                &exynos_drm_platform_driver,
 220                DRM_VIRTUAL_DEVICE
 221        }
 222};
 223
 224static int compare_dev(struct device *dev, void *data)
 225{
 226        return dev == (struct device *)data;
 227}
 228
 229static struct component_match *exynos_drm_match_add(struct device *dev)
 230{
 231        struct component_match *match = NULL;
 232        int i;
 233
 234        for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
 235                struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
 236                struct device *p = NULL, *d;
 237
 238                if (!info->driver || !(info->flags & DRM_COMPONENT_DRIVER))
 239                        continue;
 240
 241                while ((d = platform_find_device_by_driver(p, &info->driver->driver))) {
 242                        put_device(p);
 243
 244                        if (!(info->flags & DRM_FIMC_DEVICE) ||
 245                            exynos_drm_check_fimc_device(d) == 0)
 246                                component_match_add(dev, &match,
 247                                                    compare_dev, d);
 248                        p = d;
 249                }
 250                put_device(p);
 251        }
 252
 253        return match ?: ERR_PTR(-ENODEV);
 254}
 255
 256static int exynos_drm_bind(struct device *dev)
 257{
 258        struct exynos_drm_private *private;
 259        struct drm_encoder *encoder;
 260        struct drm_device *drm;
 261        unsigned int clone_mask;
 262        int ret;
 263
 264        drm = drm_dev_alloc(&exynos_drm_driver, dev);
 265        if (IS_ERR(drm))
 266                return PTR_ERR(drm);
 267
 268        private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
 269        if (!private) {
 270                ret = -ENOMEM;
 271                goto err_free_drm;
 272        }
 273
 274        init_waitqueue_head(&private->wait);
 275        spin_lock_init(&private->lock);
 276
 277        dev_set_drvdata(dev, drm);
 278        drm->dev_private = (void *)private;
 279
 280        drm_mode_config_init(drm);
 281
 282        exynos_drm_mode_config_init(drm);
 283
 284        /* setup possible_clones. */
 285        clone_mask = 0;
 286        list_for_each_entry(encoder, &drm->mode_config.encoder_list, head)
 287                clone_mask |= drm_encoder_mask(encoder);
 288
 289        list_for_each_entry(encoder, &drm->mode_config.encoder_list, head)
 290                encoder->possible_clones = clone_mask;
 291
 292        /* Try to bind all sub drivers. */
 293        ret = component_bind_all(drm->dev, drm);
 294        if (ret)
 295                goto err_mode_config_cleanup;
 296
 297        ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
 298        if (ret)
 299                goto err_unbind_all;
 300
 301        drm_mode_config_reset(drm);
 302
 303        /* init kms poll for handling hpd */
 304        drm_kms_helper_poll_init(drm);
 305
 306        ret = exynos_drm_fbdev_init(drm);
 307        if (ret)
 308                goto err_cleanup_poll;
 309
 310        /* register the DRM device */
 311        ret = drm_dev_register(drm, 0);
 312        if (ret < 0)
 313                goto err_cleanup_fbdev;
 314
 315        return 0;
 316
 317err_cleanup_fbdev:
 318        exynos_drm_fbdev_fini(drm);
 319err_cleanup_poll:
 320        drm_kms_helper_poll_fini(drm);
 321err_unbind_all:
 322        component_unbind_all(drm->dev, drm);
 323err_mode_config_cleanup:
 324        drm_mode_config_cleanup(drm);
 325        exynos_drm_cleanup_dma(drm);
 326        kfree(private);
 327err_free_drm:
 328        drm_dev_put(drm);
 329
 330        return ret;
 331}
 332
 333static void exynos_drm_unbind(struct device *dev)
 334{
 335        struct drm_device *drm = dev_get_drvdata(dev);
 336
 337        drm_dev_unregister(drm);
 338
 339        exynos_drm_fbdev_fini(drm);
 340        drm_kms_helper_poll_fini(drm);
 341
 342        component_unbind_all(drm->dev, drm);
 343        drm_mode_config_cleanup(drm);
 344        exynos_drm_cleanup_dma(drm);
 345
 346        kfree(drm->dev_private);
 347        drm->dev_private = NULL;
 348        dev_set_drvdata(dev, NULL);
 349
 350        drm_dev_put(drm);
 351}
 352
 353static const struct component_master_ops exynos_drm_ops = {
 354        .bind           = exynos_drm_bind,
 355        .unbind         = exynos_drm_unbind,
 356};
 357
 358static int exynos_drm_platform_probe(struct platform_device *pdev)
 359{
 360        struct component_match *match;
 361
 362        pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 363
 364        match = exynos_drm_match_add(&pdev->dev);
 365        if (IS_ERR(match))
 366                return PTR_ERR(match);
 367
 368        return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
 369                                               match);
 370}
 371
 372static int exynos_drm_platform_remove(struct platform_device *pdev)
 373{
 374        component_master_del(&pdev->dev, &exynos_drm_ops);
 375        return 0;
 376}
 377
 378static struct platform_driver exynos_drm_platform_driver = {
 379        .probe  = exynos_drm_platform_probe,
 380        .remove = exynos_drm_platform_remove,
 381        .driver = {
 382                .name   = "exynos-drm",
 383                .pm     = &exynos_drm_pm_ops,
 384        },
 385};
 386
 387static void exynos_drm_unregister_devices(void)
 388{
 389        int i;
 390
 391        for (i = ARRAY_SIZE(exynos_drm_drivers) - 1; i >= 0; --i) {
 392                struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
 393                struct device *dev;
 394
 395                if (!info->driver || !(info->flags & DRM_VIRTUAL_DEVICE))
 396                        continue;
 397
 398                while ((dev = platform_find_device_by_driver(NULL,
 399                                                &info->driver->driver))) {
 400                        put_device(dev);
 401                        platform_device_unregister(to_platform_device(dev));
 402                }
 403        }
 404}
 405
 406static int exynos_drm_register_devices(void)
 407{
 408        struct platform_device *pdev;
 409        int i;
 410
 411        for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
 412                struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
 413
 414                if (!info->driver || !(info->flags & DRM_VIRTUAL_DEVICE))
 415                        continue;
 416
 417                pdev = platform_device_register_simple(
 418                                        info->driver->driver.name, -1, NULL, 0);
 419                if (IS_ERR(pdev))
 420                        goto fail;
 421        }
 422
 423        return 0;
 424fail:
 425        exynos_drm_unregister_devices();
 426        return PTR_ERR(pdev);
 427}
 428
 429static void exynos_drm_unregister_drivers(void)
 430{
 431        int i;
 432
 433        for (i = ARRAY_SIZE(exynos_drm_drivers) - 1; i >= 0; --i) {
 434                struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
 435
 436                if (!info->driver)
 437                        continue;
 438
 439                platform_driver_unregister(info->driver);
 440        }
 441}
 442
 443static int exynos_drm_register_drivers(void)
 444{
 445        int i, ret;
 446
 447        for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
 448                struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
 449
 450                if (!info->driver)
 451                        continue;
 452
 453                ret = platform_driver_register(info->driver);
 454                if (ret)
 455                        goto fail;
 456        }
 457        return 0;
 458fail:
 459        exynos_drm_unregister_drivers();
 460        return ret;
 461}
 462
 463static int exynos_drm_init(void)
 464{
 465        int ret;
 466
 467        ret = exynos_drm_register_devices();
 468        if (ret)
 469                return ret;
 470
 471        ret = exynos_drm_register_drivers();
 472        if (ret)
 473                goto err_unregister_pdevs;
 474
 475        return 0;
 476
 477err_unregister_pdevs:
 478        exynos_drm_unregister_devices();
 479
 480        return ret;
 481}
 482
 483static void exynos_drm_exit(void)
 484{
 485        exynos_drm_unregister_drivers();
 486        exynos_drm_unregister_devices();
 487}
 488
 489module_init(exynos_drm_init);
 490module_exit(exynos_drm_exit);
 491
 492MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
 493MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
 494MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
 495MODULE_DESCRIPTION("Samsung SoC DRM Driver");
 496MODULE_LICENSE("GPL");
 497