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