linux/drivers/gpu/drm/exynos/exynos_drm_g2d.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2012 Samsung Electronics Co.Ltd
   3 * Authors: Joonyoung Shim <jy0922.shim@samsung.com>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundationr
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/clk.h>
  12#include <linux/err.h>
  13#include <linux/interrupt.h>
  14#include <linux/io.h>
  15#include <linux/platform_device.h>
  16#include <linux/pm_runtime.h>
  17#include <linux/slab.h>
  18#include <linux/workqueue.h>
  19#include <linux/dma-mapping.h>
  20#include <linux/dma-attrs.h>
  21#include <linux/of.h>
  22
  23#include <drm/drmP.h>
  24#include <drm/exynos_drm.h>
  25#include "exynos_drm_drv.h"
  26#include "exynos_drm_g2d.h"
  27#include "exynos_drm_gem.h"
  28#include "exynos_drm_iommu.h"
  29
  30#define G2D_HW_MAJOR_VER                4
  31#define G2D_HW_MINOR_VER                1
  32
  33/* vaild register range set from user: 0x0104 ~ 0x0880 */
  34#define G2D_VALID_START                 0x0104
  35#define G2D_VALID_END                   0x0880
  36
  37/* general registers */
  38#define G2D_SOFT_RESET                  0x0000
  39#define G2D_INTEN                       0x0004
  40#define G2D_INTC_PEND                   0x000C
  41#define G2D_DMA_SFR_BASE_ADDR           0x0080
  42#define G2D_DMA_COMMAND                 0x0084
  43#define G2D_DMA_STATUS                  0x008C
  44#define G2D_DMA_HOLD_CMD                0x0090
  45
  46/* command registers */
  47#define G2D_BITBLT_START                0x0100
  48
  49/* registers for base address */
  50#define G2D_SRC_BASE_ADDR               0x0304
  51#define G2D_SRC_COLOR_MODE              0x030C
  52#define G2D_SRC_LEFT_TOP                0x0310
  53#define G2D_SRC_RIGHT_BOTTOM            0x0314
  54#define G2D_SRC_PLANE2_BASE_ADDR        0x0318
  55#define G2D_DST_BASE_ADDR               0x0404
  56#define G2D_DST_COLOR_MODE              0x040C
  57#define G2D_DST_LEFT_TOP                0x0410
  58#define G2D_DST_RIGHT_BOTTOM            0x0414
  59#define G2D_DST_PLANE2_BASE_ADDR        0x0418
  60#define G2D_PAT_BASE_ADDR               0x0500
  61#define G2D_MSK_BASE_ADDR               0x0520
  62
  63/* G2D_SOFT_RESET */
  64#define G2D_SFRCLEAR                    (1 << 1)
  65#define G2D_R                           (1 << 0)
  66
  67/* G2D_INTEN */
  68#define G2D_INTEN_ACF                   (1 << 3)
  69#define G2D_INTEN_UCF                   (1 << 2)
  70#define G2D_INTEN_GCF                   (1 << 1)
  71#define G2D_INTEN_SCF                   (1 << 0)
  72
  73/* G2D_INTC_PEND */
  74#define G2D_INTP_ACMD_FIN               (1 << 3)
  75#define G2D_INTP_UCMD_FIN               (1 << 2)
  76#define G2D_INTP_GCMD_FIN               (1 << 1)
  77#define G2D_INTP_SCMD_FIN               (1 << 0)
  78
  79/* G2D_DMA_COMMAND */
  80#define G2D_DMA_HALT                    (1 << 2)
  81#define G2D_DMA_CONTINUE                (1 << 1)
  82#define G2D_DMA_START                   (1 << 0)
  83
  84/* G2D_DMA_STATUS */
  85#define G2D_DMA_LIST_DONE_COUNT         (0xFF << 17)
  86#define G2D_DMA_BITBLT_DONE_COUNT       (0xFFFF << 1)
  87#define G2D_DMA_DONE                    (1 << 0)
  88#define G2D_DMA_LIST_DONE_COUNT_OFFSET  17
  89
  90/* G2D_DMA_HOLD_CMD */
  91#define G2D_USER_HOLD                   (1 << 2)
  92#define G2D_LIST_HOLD                   (1 << 1)
  93#define G2D_BITBLT_HOLD                 (1 << 0)
  94
  95/* G2D_BITBLT_START */
  96#define G2D_START_CASESEL               (1 << 2)
  97#define G2D_START_NHOLT                 (1 << 1)
  98#define G2D_START_BITBLT                (1 << 0)
  99
 100/* buffer color format */
 101#define G2D_FMT_XRGB8888                0
 102#define G2D_FMT_ARGB8888                1
 103#define G2D_FMT_RGB565                  2
 104#define G2D_FMT_XRGB1555                3
 105#define G2D_FMT_ARGB1555                4
 106#define G2D_FMT_XRGB4444                5
 107#define G2D_FMT_ARGB4444                6
 108#define G2D_FMT_PACKED_RGB888           7
 109#define G2D_FMT_A8                      11
 110#define G2D_FMT_L8                      12
 111
 112/* buffer valid length */
 113#define G2D_LEN_MIN                     1
 114#define G2D_LEN_MAX                     8000
 115
 116#define G2D_CMDLIST_SIZE                (PAGE_SIZE / 4)
 117#define G2D_CMDLIST_NUM                 64
 118#define G2D_CMDLIST_POOL_SIZE           (G2D_CMDLIST_SIZE * G2D_CMDLIST_NUM)
 119#define G2D_CMDLIST_DATA_NUM            (G2D_CMDLIST_SIZE / sizeof(u32) - 2)
 120
 121/* maximum buffer pool size of userptr is 64MB as default */
 122#define MAX_POOL                (64 * 1024 * 1024)
 123
 124enum {
 125        BUF_TYPE_GEM = 1,
 126        BUF_TYPE_USERPTR,
 127};
 128
 129enum g2d_reg_type {
 130        REG_TYPE_NONE = -1,
 131        REG_TYPE_SRC,
 132        REG_TYPE_SRC_PLANE2,
 133        REG_TYPE_DST,
 134        REG_TYPE_DST_PLANE2,
 135        REG_TYPE_PAT,
 136        REG_TYPE_MSK,
 137        MAX_REG_TYPE_NR
 138};
 139
 140/* cmdlist data structure */
 141struct g2d_cmdlist {
 142        u32             head;
 143        unsigned long   data[G2D_CMDLIST_DATA_NUM];
 144        u32             last;   /* last data offset */
 145};
 146
 147/*
 148 * A structure of buffer description
 149 *
 150 * @format: color format
 151 * @left_x: the x coordinates of left top corner
 152 * @top_y: the y coordinates of left top corner
 153 * @right_x: the x coordinates of right bottom corner
 154 * @bottom_y: the y coordinates of right bottom corner
 155 *
 156 */
 157struct g2d_buf_desc {
 158        unsigned int    format;
 159        unsigned int    left_x;
 160        unsigned int    top_y;
 161        unsigned int    right_x;
 162        unsigned int    bottom_y;
 163};
 164
 165/*
 166 * A structure of buffer information
 167 *
 168 * @map_nr: manages the number of mapped buffers
 169 * @reg_types: stores regitster type in the order of requested command
 170 * @handles: stores buffer handle in its reg_type position
 171 * @types: stores buffer type in its reg_type position
 172 * @descs: stores buffer description in its reg_type position
 173 *
 174 */
 175struct g2d_buf_info {
 176        unsigned int            map_nr;
 177        enum g2d_reg_type       reg_types[MAX_REG_TYPE_NR];
 178        unsigned long           handles[MAX_REG_TYPE_NR];
 179        unsigned int            types[MAX_REG_TYPE_NR];
 180        struct g2d_buf_desc     descs[MAX_REG_TYPE_NR];
 181};
 182
 183struct drm_exynos_pending_g2d_event {
 184        struct drm_pending_event        base;
 185        struct drm_exynos_g2d_event     event;
 186};
 187
 188struct g2d_cmdlist_userptr {
 189        struct list_head        list;
 190        dma_addr_t              dma_addr;
 191        unsigned long           userptr;
 192        unsigned long           size;
 193        struct page             **pages;
 194        unsigned int            npages;
 195        struct sg_table         *sgt;
 196        struct vm_area_struct   *vma;
 197        atomic_t                refcount;
 198        bool                    in_pool;
 199        bool                    out_of_list;
 200};
 201struct g2d_cmdlist_node {
 202        struct list_head        list;
 203        struct g2d_cmdlist      *cmdlist;
 204        dma_addr_t              dma_addr;
 205        struct g2d_buf_info     buf_info;
 206
 207        struct drm_exynos_pending_g2d_event     *event;
 208};
 209
 210struct g2d_runqueue_node {
 211        struct list_head        list;
 212        struct list_head        run_cmdlist;
 213        struct list_head        event_list;
 214        struct drm_file         *filp;
 215        pid_t                   pid;
 216        struct completion       complete;
 217        int                     async;
 218};
 219
 220struct g2d_data {
 221        struct device                   *dev;
 222        struct clk                      *gate_clk;
 223        void __iomem                    *regs;
 224        int                             irq;
 225        struct workqueue_struct         *g2d_workq;
 226        struct work_struct              runqueue_work;
 227        struct exynos_drm_subdrv        subdrv;
 228        bool                            suspended;
 229
 230        /* cmdlist */
 231        struct g2d_cmdlist_node         *cmdlist_node;
 232        struct list_head                free_cmdlist;
 233        struct mutex                    cmdlist_mutex;
 234        dma_addr_t                      cmdlist_pool;
 235        void                            *cmdlist_pool_virt;
 236        struct dma_attrs                cmdlist_dma_attrs;
 237
 238        /* runqueue*/
 239        struct g2d_runqueue_node        *runqueue_node;
 240        struct list_head                runqueue;
 241        struct mutex                    runqueue_mutex;
 242        struct kmem_cache               *runqueue_slab;
 243
 244        unsigned long                   current_pool;
 245        unsigned long                   max_pool;
 246};
 247
 248static int g2d_init_cmdlist(struct g2d_data *g2d)
 249{
 250        struct device *dev = g2d->dev;
 251        struct g2d_cmdlist_node *node = g2d->cmdlist_node;
 252        struct exynos_drm_subdrv *subdrv = &g2d->subdrv;
 253        int nr;
 254        int ret;
 255        struct g2d_buf_info *buf_info;
 256
 257        init_dma_attrs(&g2d->cmdlist_dma_attrs);
 258        dma_set_attr(DMA_ATTR_WRITE_COMBINE, &g2d->cmdlist_dma_attrs);
 259
 260        g2d->cmdlist_pool_virt = dma_alloc_attrs(subdrv->drm_dev->dev,
 261                                                G2D_CMDLIST_POOL_SIZE,
 262                                                &g2d->cmdlist_pool, GFP_KERNEL,
 263                                                &g2d->cmdlist_dma_attrs);
 264        if (!g2d->cmdlist_pool_virt) {
 265                dev_err(dev, "failed to allocate dma memory\n");
 266                return -ENOMEM;
 267        }
 268
 269        node = kcalloc(G2D_CMDLIST_NUM, sizeof(*node), GFP_KERNEL);
 270        if (!node) {
 271                dev_err(dev, "failed to allocate memory\n");
 272                ret = -ENOMEM;
 273                goto err;
 274        }
 275
 276        for (nr = 0; nr < G2D_CMDLIST_NUM; nr++) {
 277                unsigned int i;
 278
 279                node[nr].cmdlist =
 280                        g2d->cmdlist_pool_virt + nr * G2D_CMDLIST_SIZE;
 281                node[nr].dma_addr =
 282                        g2d->cmdlist_pool + nr * G2D_CMDLIST_SIZE;
 283
 284                buf_info = &node[nr].buf_info;
 285                for (i = 0; i < MAX_REG_TYPE_NR; i++)
 286                        buf_info->reg_types[i] = REG_TYPE_NONE;
 287
 288                list_add_tail(&node[nr].list, &g2d->free_cmdlist);
 289        }
 290
 291        return 0;
 292
 293err:
 294        dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE,
 295                        g2d->cmdlist_pool_virt,
 296                        g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs);
 297        return ret;
 298}
 299
 300static void g2d_fini_cmdlist(struct g2d_data *g2d)
 301{
 302        struct exynos_drm_subdrv *subdrv = &g2d->subdrv;
 303
 304        kfree(g2d->cmdlist_node);
 305
 306        if (g2d->cmdlist_pool_virt && g2d->cmdlist_pool) {
 307                dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE,
 308                                g2d->cmdlist_pool_virt,
 309                                g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs);
 310        }
 311}
 312
 313static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d)
 314{
 315        struct device *dev = g2d->dev;
 316        struct g2d_cmdlist_node *node;
 317
 318        mutex_lock(&g2d->cmdlist_mutex);
 319        if (list_empty(&g2d->free_cmdlist)) {
 320                dev_err(dev, "there is no free cmdlist\n");
 321                mutex_unlock(&g2d->cmdlist_mutex);
 322                return NULL;
 323        }
 324
 325        node = list_first_entry(&g2d->free_cmdlist, struct g2d_cmdlist_node,
 326                                list);
 327        list_del_init(&node->list);
 328        mutex_unlock(&g2d->cmdlist_mutex);
 329
 330        return node;
 331}
 332
 333static void g2d_put_cmdlist(struct g2d_data *g2d, struct g2d_cmdlist_node *node)
 334{
 335        mutex_lock(&g2d->cmdlist_mutex);
 336        list_move_tail(&node->list, &g2d->free_cmdlist);
 337        mutex_unlock(&g2d->cmdlist_mutex);
 338}
 339
 340static void g2d_add_cmdlist_to_inuse(struct exynos_drm_g2d_private *g2d_priv,
 341                                     struct g2d_cmdlist_node *node)
 342{
 343        struct g2d_cmdlist_node *lnode;
 344
 345        if (list_empty(&g2d_priv->inuse_cmdlist))
 346                goto add_to_list;
 347
 348        /* this links to base address of new cmdlist */
 349        lnode = list_entry(g2d_priv->inuse_cmdlist.prev,
 350                                struct g2d_cmdlist_node, list);
 351        lnode->cmdlist->data[lnode->cmdlist->last] = node->dma_addr;
 352
 353add_to_list:
 354        list_add_tail(&node->list, &g2d_priv->inuse_cmdlist);
 355
 356        if (node->event)
 357                list_add_tail(&node->event->base.link, &g2d_priv->event_list);
 358}
 359
 360static void g2d_userptr_put_dma_addr(struct drm_device *drm_dev,
 361                                        unsigned long obj,
 362                                        bool force)
 363{
 364        struct g2d_cmdlist_userptr *g2d_userptr =
 365                                        (struct g2d_cmdlist_userptr *)obj;
 366
 367        if (!obj)
 368                return;
 369
 370        if (force)
 371                goto out;
 372
 373        atomic_dec(&g2d_userptr->refcount);
 374
 375        if (atomic_read(&g2d_userptr->refcount) > 0)
 376                return;
 377
 378        if (g2d_userptr->in_pool)
 379                return;
 380
 381out:
 382        exynos_gem_unmap_sgt_from_dma(drm_dev, g2d_userptr->sgt,
 383                                        DMA_BIDIRECTIONAL);
 384
 385        exynos_gem_put_pages_to_userptr(g2d_userptr->pages,
 386                                        g2d_userptr->npages,
 387                                        g2d_userptr->vma);
 388
 389        exynos_gem_put_vma(g2d_userptr->vma);
 390
 391        if (!g2d_userptr->out_of_list)
 392                list_del_init(&g2d_userptr->list);
 393
 394        sg_free_table(g2d_userptr->sgt);
 395        kfree(g2d_userptr->sgt);
 396
 397        drm_free_large(g2d_userptr->pages);
 398        kfree(g2d_userptr);
 399}
 400
 401static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
 402                                        unsigned long userptr,
 403                                        unsigned long size,
 404                                        struct drm_file *filp,
 405                                        unsigned long *obj)
 406{
 407        struct drm_exynos_file_private *file_priv = filp->driver_priv;
 408        struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
 409        struct g2d_cmdlist_userptr *g2d_userptr;
 410        struct g2d_data *g2d;
 411        struct page **pages;
 412        struct sg_table *sgt;
 413        struct vm_area_struct *vma;
 414        unsigned long start, end;
 415        unsigned int npages, offset;
 416        int ret;
 417
 418        if (!size) {
 419                DRM_ERROR("invalid userptr size.\n");
 420                return ERR_PTR(-EINVAL);
 421        }
 422
 423        g2d = dev_get_drvdata(g2d_priv->dev);
 424
 425        /* check if userptr already exists in userptr_list. */
 426        list_for_each_entry(g2d_userptr, &g2d_priv->userptr_list, list) {
 427                if (g2d_userptr->userptr == userptr) {
 428                        /*
 429                         * also check size because there could be same address
 430                         * and different size.
 431                         */
 432                        if (g2d_userptr->size == size) {
 433                                atomic_inc(&g2d_userptr->refcount);
 434                                *obj = (unsigned long)g2d_userptr;
 435
 436                                return &g2d_userptr->dma_addr;
 437                        }
 438
 439                        /*
 440                         * at this moment, maybe g2d dma is accessing this
 441                         * g2d_userptr memory region so just remove this
 442                         * g2d_userptr object from userptr_list not to be
 443                         * referred again and also except it the userptr
 444                         * pool to be released after the dma access completion.
 445                         */
 446                        g2d_userptr->out_of_list = true;
 447                        g2d_userptr->in_pool = false;
 448                        list_del_init(&g2d_userptr->list);
 449
 450                        break;
 451                }
 452        }
 453
 454        g2d_userptr = kzalloc(sizeof(*g2d_userptr), GFP_KERNEL);
 455        if (!g2d_userptr)
 456                return ERR_PTR(-ENOMEM);
 457
 458        atomic_set(&g2d_userptr->refcount, 1);
 459
 460        start = userptr & PAGE_MASK;
 461        offset = userptr & ~PAGE_MASK;
 462        end = PAGE_ALIGN(userptr + size);
 463        npages = (end - start) >> PAGE_SHIFT;
 464        g2d_userptr->npages = npages;
 465
 466        pages = drm_calloc_large(npages, sizeof(struct page *));
 467        if (!pages) {
 468                DRM_ERROR("failed to allocate pages.\n");
 469                ret = -ENOMEM;
 470                goto err_free;
 471        }
 472
 473        down_read(&current->mm->mmap_sem);
 474        vma = find_vma(current->mm, userptr);
 475        if (!vma) {
 476                up_read(&current->mm->mmap_sem);
 477                DRM_ERROR("failed to get vm region.\n");
 478                ret = -EFAULT;
 479                goto err_free_pages;
 480        }
 481
 482        if (vma->vm_end < userptr + size) {
 483                up_read(&current->mm->mmap_sem);
 484                DRM_ERROR("vma is too small.\n");
 485                ret = -EFAULT;
 486                goto err_free_pages;
 487        }
 488
 489        g2d_userptr->vma = exynos_gem_get_vma(vma);
 490        if (!g2d_userptr->vma) {
 491                up_read(&current->mm->mmap_sem);
 492                DRM_ERROR("failed to copy vma.\n");
 493                ret = -ENOMEM;
 494                goto err_free_pages;
 495        }
 496
 497        g2d_userptr->size = size;
 498
 499        ret = exynos_gem_get_pages_from_userptr(start & PAGE_MASK,
 500                                                npages, pages, vma);
 501        if (ret < 0) {
 502                up_read(&current->mm->mmap_sem);
 503                DRM_ERROR("failed to get user pages from userptr.\n");
 504                goto err_put_vma;
 505        }
 506
 507        up_read(&current->mm->mmap_sem);
 508        g2d_userptr->pages = pages;
 509
 510        sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
 511        if (!sgt) {
 512                ret = -ENOMEM;
 513                goto err_free_userptr;
 514        }
 515
 516        ret = sg_alloc_table_from_pages(sgt, pages, npages, offset,
 517                                        size, GFP_KERNEL);
 518        if (ret < 0) {
 519                DRM_ERROR("failed to get sgt from pages.\n");
 520                goto err_free_sgt;
 521        }
 522
 523        g2d_userptr->sgt = sgt;
 524
 525        ret = exynos_gem_map_sgt_with_dma(drm_dev, g2d_userptr->sgt,
 526                                                DMA_BIDIRECTIONAL);
 527        if (ret < 0) {
 528                DRM_ERROR("failed to map sgt with dma region.\n");
 529                goto err_sg_free_table;
 530        }
 531
 532        g2d_userptr->dma_addr = sgt->sgl[0].dma_address;
 533        g2d_userptr->userptr = userptr;
 534
 535        list_add_tail(&g2d_userptr->list, &g2d_priv->userptr_list);
 536
 537        if (g2d->current_pool + (npages << PAGE_SHIFT) < g2d->max_pool) {
 538                g2d->current_pool += npages << PAGE_SHIFT;
 539                g2d_userptr->in_pool = true;
 540        }
 541
 542        *obj = (unsigned long)g2d_userptr;
 543
 544        return &g2d_userptr->dma_addr;
 545
 546err_sg_free_table:
 547        sg_free_table(sgt);
 548
 549err_free_sgt:
 550        kfree(sgt);
 551
 552err_free_userptr:
 553        exynos_gem_put_pages_to_userptr(g2d_userptr->pages,
 554                                        g2d_userptr->npages,
 555                                        g2d_userptr->vma);
 556
 557err_put_vma:
 558        exynos_gem_put_vma(g2d_userptr->vma);
 559
 560err_free_pages:
 561        drm_free_large(pages);
 562
 563err_free:
 564        kfree(g2d_userptr);
 565
 566        return ERR_PTR(ret);
 567}
 568
 569static void g2d_userptr_free_all(struct drm_device *drm_dev,
 570                                        struct g2d_data *g2d,
 571                                        struct drm_file *filp)
 572{
 573        struct drm_exynos_file_private *file_priv = filp->driver_priv;
 574        struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
 575        struct g2d_cmdlist_userptr *g2d_userptr, *n;
 576
 577        list_for_each_entry_safe(g2d_userptr, n, &g2d_priv->userptr_list, list)
 578                if (g2d_userptr->in_pool)
 579                        g2d_userptr_put_dma_addr(drm_dev,
 580                                                (unsigned long)g2d_userptr,
 581                                                true);
 582
 583        g2d->current_pool = 0;
 584}
 585
 586static enum g2d_reg_type g2d_get_reg_type(int reg_offset)
 587{
 588        enum g2d_reg_type reg_type;
 589
 590        switch (reg_offset) {
 591        case G2D_SRC_BASE_ADDR:
 592        case G2D_SRC_COLOR_MODE:
 593        case G2D_SRC_LEFT_TOP:
 594        case G2D_SRC_RIGHT_BOTTOM:
 595                reg_type = REG_TYPE_SRC;
 596                break;
 597        case G2D_SRC_PLANE2_BASE_ADDR:
 598                reg_type = REG_TYPE_SRC_PLANE2;
 599                break;
 600        case G2D_DST_BASE_ADDR:
 601        case G2D_DST_COLOR_MODE:
 602        case G2D_DST_LEFT_TOP:
 603        case G2D_DST_RIGHT_BOTTOM:
 604                reg_type = REG_TYPE_DST;
 605                break;
 606        case G2D_DST_PLANE2_BASE_ADDR:
 607                reg_type = REG_TYPE_DST_PLANE2;
 608                break;
 609        case G2D_PAT_BASE_ADDR:
 610                reg_type = REG_TYPE_PAT;
 611                break;
 612        case G2D_MSK_BASE_ADDR:
 613                reg_type = REG_TYPE_MSK;
 614                break;
 615        default:
 616                reg_type = REG_TYPE_NONE;
 617                DRM_ERROR("Unknown register offset![%d]\n", reg_offset);
 618                break;
 619        }
 620
 621        return reg_type;
 622}
 623
 624static unsigned long g2d_get_buf_bpp(unsigned int format)
 625{
 626        unsigned long bpp;
 627
 628        switch (format) {
 629        case G2D_FMT_XRGB8888:
 630        case G2D_FMT_ARGB8888:
 631                bpp = 4;
 632                break;
 633        case G2D_FMT_RGB565:
 634        case G2D_FMT_XRGB1555:
 635        case G2D_FMT_ARGB1555:
 636        case G2D_FMT_XRGB4444:
 637        case G2D_FMT_ARGB4444:
 638                bpp = 2;
 639                break;
 640        case G2D_FMT_PACKED_RGB888:
 641                bpp = 3;
 642                break;
 643        default:
 644                bpp = 1;
 645                break;
 646        }
 647
 648        return bpp;
 649}
 650
 651static bool g2d_check_buf_desc_is_valid(struct g2d_buf_desc *buf_desc,
 652                                                enum g2d_reg_type reg_type,
 653                                                unsigned long size)
 654{
 655        unsigned int width, height;
 656        unsigned long area;
 657
 658        /*
 659         * check source and destination buffers only.
 660         * so the others are always valid.
 661         */
 662        if (reg_type != REG_TYPE_SRC && reg_type != REG_TYPE_DST)
 663                return true;
 664
 665        width = buf_desc->right_x - buf_desc->left_x;
 666        if (width < G2D_LEN_MIN || width > G2D_LEN_MAX) {
 667                DRM_ERROR("width[%u] is out of range!\n", width);
 668                return false;
 669        }
 670
 671        height = buf_desc->bottom_y - buf_desc->top_y;
 672        if (height < G2D_LEN_MIN || height > G2D_LEN_MAX) {
 673                DRM_ERROR("height[%u] is out of range!\n", height);
 674                return false;
 675        }
 676
 677        area = (unsigned long)width * (unsigned long)height *
 678                                        g2d_get_buf_bpp(buf_desc->format);
 679        if (area > size) {
 680                DRM_ERROR("area[%lu] is out of range[%lu]!\n", area, size);
 681                return false;
 682        }
 683
 684        return true;
 685}
 686
 687static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
 688                                struct g2d_cmdlist_node *node,
 689                                struct drm_device *drm_dev,
 690                                struct drm_file *file)
 691{
 692        struct g2d_cmdlist *cmdlist = node->cmdlist;
 693        struct g2d_buf_info *buf_info = &node->buf_info;
 694        int offset;
 695        int ret;
 696        int i;
 697
 698        for (i = 0; i < buf_info->map_nr; i++) {
 699                struct g2d_buf_desc *buf_desc;
 700                enum g2d_reg_type reg_type;
 701                int reg_pos;
 702                unsigned long handle;
 703                dma_addr_t *addr;
 704
 705                reg_pos = cmdlist->last - 2 * (i + 1);
 706
 707                offset = cmdlist->data[reg_pos];
 708                handle = cmdlist->data[reg_pos + 1];
 709
 710                reg_type = g2d_get_reg_type(offset);
 711                if (reg_type == REG_TYPE_NONE) {
 712                        ret = -EFAULT;
 713                        goto err;
 714                }
 715
 716                buf_desc = &buf_info->descs[reg_type];
 717
 718                if (buf_info->types[reg_type] == BUF_TYPE_GEM) {
 719                        unsigned long size;
 720
 721                        size = exynos_drm_gem_get_size(drm_dev, handle, file);
 722                        if (!size) {
 723                                ret = -EFAULT;
 724                                goto err;
 725                        }
 726
 727                        if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type,
 728                                                                        size)) {
 729                                ret = -EFAULT;
 730                                goto err;
 731                        }
 732
 733                        addr = exynos_drm_gem_get_dma_addr(drm_dev, handle,
 734                                                                file);
 735                        if (IS_ERR(addr)) {
 736                                ret = -EFAULT;
 737                                goto err;
 738                        }
 739                } else {
 740                        struct drm_exynos_g2d_userptr g2d_userptr;
 741
 742                        if (copy_from_user(&g2d_userptr, (void __user *)handle,
 743                                sizeof(struct drm_exynos_g2d_userptr))) {
 744                                ret = -EFAULT;
 745                                goto err;
 746                        }
 747
 748                        if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type,
 749                                                        g2d_userptr.size)) {
 750                                ret = -EFAULT;
 751                                goto err;
 752                        }
 753
 754                        addr = g2d_userptr_get_dma_addr(drm_dev,
 755                                                        g2d_userptr.userptr,
 756                                                        g2d_userptr.size,
 757                                                        file,
 758                                                        &handle);
 759                        if (IS_ERR(addr)) {
 760                                ret = -EFAULT;
 761                                goto err;
 762                        }
 763                }
 764
 765                cmdlist->data[reg_pos + 1] = *addr;
 766                buf_info->reg_types[i] = reg_type;
 767                buf_info->handles[reg_type] = handle;
 768        }
 769
 770        return 0;
 771
 772err:
 773        buf_info->map_nr = i;
 774        return ret;
 775}
 776
 777static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d,
 778                                  struct g2d_cmdlist_node *node,
 779                                  struct drm_file *filp)
 780{
 781        struct exynos_drm_subdrv *subdrv = &g2d->subdrv;
 782        struct g2d_buf_info *buf_info = &node->buf_info;
 783        int i;
 784
 785        for (i = 0; i < buf_info->map_nr; i++) {
 786                struct g2d_buf_desc *buf_desc;
 787                enum g2d_reg_type reg_type;
 788                unsigned long handle;
 789
 790                reg_type = buf_info->reg_types[i];
 791
 792                buf_desc = &buf_info->descs[reg_type];
 793                handle = buf_info->handles[reg_type];
 794
 795                if (buf_info->types[reg_type] == BUF_TYPE_GEM)
 796                        exynos_drm_gem_put_dma_addr(subdrv->drm_dev, handle,
 797                                                        filp);
 798                else
 799                        g2d_userptr_put_dma_addr(subdrv->drm_dev, handle,
 800                                                        false);
 801
 802                buf_info->reg_types[i] = REG_TYPE_NONE;
 803                buf_info->handles[reg_type] = 0;
 804                buf_info->types[reg_type] = 0;
 805                memset(buf_desc, 0x00, sizeof(*buf_desc));
 806        }
 807
 808        buf_info->map_nr = 0;
 809}
 810
 811static void g2d_dma_start(struct g2d_data *g2d,
 812                          struct g2d_runqueue_node *runqueue_node)
 813{
 814        struct g2d_cmdlist_node *node =
 815                                list_first_entry(&runqueue_node->run_cmdlist,
 816                                                struct g2d_cmdlist_node, list);
 817        int ret;
 818
 819        ret = pm_runtime_get_sync(g2d->dev);
 820        if (ret < 0)
 821                return;
 822
 823        writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR);
 824        writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND);
 825}
 826
 827static struct g2d_runqueue_node *g2d_get_runqueue_node(struct g2d_data *g2d)
 828{
 829        struct g2d_runqueue_node *runqueue_node;
 830
 831        if (list_empty(&g2d->runqueue))
 832                return NULL;
 833
 834        runqueue_node = list_first_entry(&g2d->runqueue,
 835                                         struct g2d_runqueue_node, list);
 836        list_del_init(&runqueue_node->list);
 837        return runqueue_node;
 838}
 839
 840static void g2d_free_runqueue_node(struct g2d_data *g2d,
 841                                   struct g2d_runqueue_node *runqueue_node)
 842{
 843        struct g2d_cmdlist_node *node;
 844
 845        if (!runqueue_node)
 846                return;
 847
 848        mutex_lock(&g2d->cmdlist_mutex);
 849        /*
 850         * commands in run_cmdlist have been completed so unmap all gem
 851         * objects in each command node so that they are unreferenced.
 852         */
 853        list_for_each_entry(node, &runqueue_node->run_cmdlist, list)
 854                g2d_unmap_cmdlist_gem(g2d, node, runqueue_node->filp);
 855        list_splice_tail_init(&runqueue_node->run_cmdlist, &g2d->free_cmdlist);
 856        mutex_unlock(&g2d->cmdlist_mutex);
 857
 858        kmem_cache_free(g2d->runqueue_slab, runqueue_node);
 859}
 860
 861static void g2d_exec_runqueue(struct g2d_data *g2d)
 862{
 863        g2d->runqueue_node = g2d_get_runqueue_node(g2d);
 864        if (g2d->runqueue_node)
 865                g2d_dma_start(g2d, g2d->runqueue_node);
 866}
 867
 868static void g2d_runqueue_worker(struct work_struct *work)
 869{
 870        struct g2d_data *g2d = container_of(work, struct g2d_data,
 871                                            runqueue_work);
 872
 873        mutex_lock(&g2d->runqueue_mutex);
 874        pm_runtime_put_sync(g2d->dev);
 875
 876        complete(&g2d->runqueue_node->complete);
 877        if (g2d->runqueue_node->async)
 878                g2d_free_runqueue_node(g2d, g2d->runqueue_node);
 879
 880        if (g2d->suspended)
 881                g2d->runqueue_node = NULL;
 882        else
 883                g2d_exec_runqueue(g2d);
 884        mutex_unlock(&g2d->runqueue_mutex);
 885}
 886
 887static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no)
 888{
 889        struct drm_device *drm_dev = g2d->subdrv.drm_dev;
 890        struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node;
 891        struct drm_exynos_pending_g2d_event *e;
 892        struct timeval now;
 893        unsigned long flags;
 894
 895        if (list_empty(&runqueue_node->event_list))
 896                return;
 897
 898        e = list_first_entry(&runqueue_node->event_list,
 899                             struct drm_exynos_pending_g2d_event, base.link);
 900
 901        do_gettimeofday(&now);
 902        e->event.tv_sec = now.tv_sec;
 903        e->event.tv_usec = now.tv_usec;
 904        e->event.cmdlist_no = cmdlist_no;
 905
 906        spin_lock_irqsave(&drm_dev->event_lock, flags);
 907        list_move_tail(&e->base.link, &e->base.file_priv->event_list);
 908        wake_up_interruptible(&e->base.file_priv->event_wait);
 909        spin_unlock_irqrestore(&drm_dev->event_lock, flags);
 910}
 911
 912static irqreturn_t g2d_irq_handler(int irq, void *dev_id)
 913{
 914        struct g2d_data *g2d = dev_id;
 915        u32 pending;
 916
 917        pending = readl_relaxed(g2d->regs + G2D_INTC_PEND);
 918        if (pending)
 919                writel_relaxed(pending, g2d->regs + G2D_INTC_PEND);
 920
 921        if (pending & G2D_INTP_GCMD_FIN) {
 922                u32 cmdlist_no = readl_relaxed(g2d->regs + G2D_DMA_STATUS);
 923
 924                cmdlist_no = (cmdlist_no & G2D_DMA_LIST_DONE_COUNT) >>
 925                                                G2D_DMA_LIST_DONE_COUNT_OFFSET;
 926
 927                g2d_finish_event(g2d, cmdlist_no);
 928
 929                writel_relaxed(0, g2d->regs + G2D_DMA_HOLD_CMD);
 930                if (!(pending & G2D_INTP_ACMD_FIN)) {
 931                        writel_relaxed(G2D_DMA_CONTINUE,
 932                                        g2d->regs + G2D_DMA_COMMAND);
 933                }
 934        }
 935
 936        if (pending & G2D_INTP_ACMD_FIN)
 937                queue_work(g2d->g2d_workq, &g2d->runqueue_work);
 938
 939        return IRQ_HANDLED;
 940}
 941
 942static int g2d_check_reg_offset(struct device *dev,
 943                                struct g2d_cmdlist_node *node,
 944                                int nr, bool for_addr)
 945{
 946        struct g2d_cmdlist *cmdlist = node->cmdlist;
 947        int reg_offset;
 948        int index;
 949        int i;
 950
 951        for (i = 0; i < nr; i++) {
 952                struct g2d_buf_info *buf_info = &node->buf_info;
 953                struct g2d_buf_desc *buf_desc;
 954                enum g2d_reg_type reg_type;
 955                unsigned long value;
 956
 957                index = cmdlist->last - 2 * (i + 1);
 958
 959                reg_offset = cmdlist->data[index] & ~0xfffff000;
 960                if (reg_offset < G2D_VALID_START || reg_offset > G2D_VALID_END)
 961                        goto err;
 962                if (reg_offset % 4)
 963                        goto err;
 964
 965                switch (reg_offset) {
 966                case G2D_SRC_BASE_ADDR:
 967                case G2D_SRC_PLANE2_BASE_ADDR:
 968                case G2D_DST_BASE_ADDR:
 969                case G2D_DST_PLANE2_BASE_ADDR:
 970                case G2D_PAT_BASE_ADDR:
 971                case G2D_MSK_BASE_ADDR:
 972                        if (!for_addr)
 973                                goto err;
 974
 975                        reg_type = g2d_get_reg_type(reg_offset);
 976                        if (reg_type == REG_TYPE_NONE)
 977                                goto err;
 978
 979                        /* check userptr buffer type. */
 980                        if ((cmdlist->data[index] & ~0x7fffffff) >> 31) {
 981                                buf_info->types[reg_type] = BUF_TYPE_USERPTR;
 982                                cmdlist->data[index] &= ~G2D_BUF_USERPTR;
 983                        } else
 984                                buf_info->types[reg_type] = BUF_TYPE_GEM;
 985                        break;
 986                case G2D_SRC_COLOR_MODE:
 987                case G2D_DST_COLOR_MODE:
 988                        if (for_addr)
 989                                goto err;
 990
 991                        reg_type = g2d_get_reg_type(reg_offset);
 992                        if (reg_type == REG_TYPE_NONE)
 993                                goto err;
 994
 995                        buf_desc = &buf_info->descs[reg_type];
 996                        value = cmdlist->data[index + 1];
 997
 998                        buf_desc->format = value & 0xf;
 999                        break;
1000                case G2D_SRC_LEFT_TOP:
1001                case G2D_DST_LEFT_TOP:
1002                        if (for_addr)
1003                                goto err;
1004
1005                        reg_type = g2d_get_reg_type(reg_offset);
1006                        if (reg_type == REG_TYPE_NONE)
1007                                goto err;
1008
1009                        buf_desc = &buf_info->descs[reg_type];
1010                        value = cmdlist->data[index + 1];
1011
1012                        buf_desc->left_x = value & 0x1fff;
1013                        buf_desc->top_y = (value & 0x1fff0000) >> 16;
1014                        break;
1015                case G2D_SRC_RIGHT_BOTTOM:
1016                case G2D_DST_RIGHT_BOTTOM:
1017                        if (for_addr)
1018                                goto err;
1019
1020                        reg_type = g2d_get_reg_type(reg_offset);
1021                        if (reg_type == REG_TYPE_NONE)
1022                                goto err;
1023
1024                        buf_desc = &buf_info->descs[reg_type];
1025                        value = cmdlist->data[index + 1];
1026
1027                        buf_desc->right_x = value & 0x1fff;
1028                        buf_desc->bottom_y = (value & 0x1fff0000) >> 16;
1029                        break;
1030                default:
1031                        if (for_addr)
1032                                goto err;
1033                        break;
1034                }
1035        }
1036
1037        return 0;
1038
1039err:
1040        dev_err(dev, "Bad register offset: 0x%lx\n", cmdlist->data[index]);
1041        return -EINVAL;
1042}
1043
1044/* ioctl functions */
1045int exynos_g2d_get_ver_ioctl(struct drm_device *drm_dev, void *data,
1046                             struct drm_file *file)
1047{
1048        struct drm_exynos_file_private *file_priv = file->driver_priv;
1049        struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
1050        struct device *dev;
1051        struct g2d_data *g2d;
1052        struct drm_exynos_g2d_get_ver *ver = data;
1053
1054        if (!g2d_priv)
1055                return -ENODEV;
1056
1057        dev = g2d_priv->dev;
1058        if (!dev)
1059                return -ENODEV;
1060
1061        g2d = dev_get_drvdata(dev);
1062        if (!g2d)
1063                return -EFAULT;
1064
1065        ver->major = G2D_HW_MAJOR_VER;
1066        ver->minor = G2D_HW_MINOR_VER;
1067
1068        return 0;
1069}
1070EXPORT_SYMBOL_GPL(exynos_g2d_get_ver_ioctl);
1071
1072int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
1073                                 struct drm_file *file)
1074{
1075        struct drm_exynos_file_private *file_priv = file->driver_priv;
1076        struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
1077        struct device *dev;
1078        struct g2d_data *g2d;
1079        struct drm_exynos_g2d_set_cmdlist *req = data;
1080        struct drm_exynos_g2d_cmd *cmd;
1081        struct drm_exynos_pending_g2d_event *e;
1082        struct g2d_cmdlist_node *node;
1083        struct g2d_cmdlist *cmdlist;
1084        unsigned long flags;
1085        int size;
1086        int ret;
1087
1088        if (!g2d_priv)
1089                return -ENODEV;
1090
1091        dev = g2d_priv->dev;
1092        if (!dev)
1093                return -ENODEV;
1094
1095        g2d = dev_get_drvdata(dev);
1096        if (!g2d)
1097                return -EFAULT;
1098
1099        node = g2d_get_cmdlist(g2d);
1100        if (!node)
1101                return -ENOMEM;
1102
1103        node->event = NULL;
1104
1105        if (req->event_type != G2D_EVENT_NOT) {
1106                spin_lock_irqsave(&drm_dev->event_lock, flags);
1107                if (file->event_space < sizeof(e->event)) {
1108                        spin_unlock_irqrestore(&drm_dev->event_lock, flags);
1109                        ret = -ENOMEM;
1110                        goto err;
1111                }
1112                file->event_space -= sizeof(e->event);
1113                spin_unlock_irqrestore(&drm_dev->event_lock, flags);
1114
1115                e = kzalloc(sizeof(*node->event), GFP_KERNEL);
1116                if (!e) {
1117                        spin_lock_irqsave(&drm_dev->event_lock, flags);
1118                        file->event_space += sizeof(e->event);
1119                        spin_unlock_irqrestore(&drm_dev->event_lock, flags);
1120
1121                        ret = -ENOMEM;
1122                        goto err;
1123                }
1124
1125                e->event.base.type = DRM_EXYNOS_G2D_EVENT;
1126                e->event.base.length = sizeof(e->event);
1127                e->event.user_data = req->user_data;
1128                e->base.event = &e->event.base;
1129                e->base.file_priv = file;
1130                e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
1131
1132                node->event = e;
1133        }
1134
1135        cmdlist = node->cmdlist;
1136
1137        cmdlist->last = 0;
1138
1139        /*
1140         * If don't clear SFR registers, the cmdlist is affected by register
1141         * values of previous cmdlist. G2D hw executes SFR clear command and
1142         * a next command at the same time then the next command is ignored and
1143         * is executed rightly from next next command, so needs a dummy command
1144         * to next command of SFR clear command.
1145         */
1146        cmdlist->data[cmdlist->last++] = G2D_SOFT_RESET;
1147        cmdlist->data[cmdlist->last++] = G2D_SFRCLEAR;
1148        cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR;
1149        cmdlist->data[cmdlist->last++] = 0;
1150
1151        /*
1152         * 'LIST_HOLD' command should be set to the DMA_HOLD_CMD_REG
1153         * and GCF bit should be set to INTEN register if user wants
1154         * G2D interrupt event once current command list execution is
1155         * finished.
1156         * Otherwise only ACF bit should be set to INTEN register so
1157         * that one interrupt is occurred after all command lists
1158         * have been completed.
1159         */
1160        if (node->event) {
1161                cmdlist->data[cmdlist->last++] = G2D_INTEN;
1162                cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF | G2D_INTEN_GCF;
1163                cmdlist->data[cmdlist->last++] = G2D_DMA_HOLD_CMD;
1164                cmdlist->data[cmdlist->last++] = G2D_LIST_HOLD;
1165        } else {
1166                cmdlist->data[cmdlist->last++] = G2D_INTEN;
1167                cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF;
1168        }
1169
1170        /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */
1171        size = cmdlist->last + req->cmd_nr * 2 + req->cmd_buf_nr * 2 + 2;
1172        if (size > G2D_CMDLIST_DATA_NUM) {
1173                dev_err(dev, "cmdlist size is too big\n");
1174                ret = -EINVAL;
1175                goto err_free_event;
1176        }
1177
1178        cmd = (struct drm_exynos_g2d_cmd *)(uint32_t)req->cmd;
1179
1180        if (copy_from_user(cmdlist->data + cmdlist->last,
1181                                (void __user *)cmd,
1182                                sizeof(*cmd) * req->cmd_nr)) {
1183                ret = -EFAULT;
1184                goto err_free_event;
1185        }
1186        cmdlist->last += req->cmd_nr * 2;
1187
1188        ret = g2d_check_reg_offset(dev, node, req->cmd_nr, false);
1189        if (ret < 0)
1190                goto err_free_event;
1191
1192        node->buf_info.map_nr = req->cmd_buf_nr;
1193        if (req->cmd_buf_nr) {
1194                struct drm_exynos_g2d_cmd *cmd_buf;
1195
1196                cmd_buf = (struct drm_exynos_g2d_cmd *)(uint32_t)req->cmd_buf;
1197
1198                if (copy_from_user(cmdlist->data + cmdlist->last,
1199                                        (void __user *)cmd_buf,
1200                                        sizeof(*cmd_buf) * req->cmd_buf_nr)) {
1201                        ret = -EFAULT;
1202                        goto err_free_event;
1203                }
1204                cmdlist->last += req->cmd_buf_nr * 2;
1205
1206                ret = g2d_check_reg_offset(dev, node, req->cmd_buf_nr, true);
1207                if (ret < 0)
1208                        goto err_free_event;
1209
1210                ret = g2d_map_cmdlist_gem(g2d, node, drm_dev, file);
1211                if (ret < 0)
1212                        goto err_unmap;
1213        }
1214
1215        cmdlist->data[cmdlist->last++] = G2D_BITBLT_START;
1216        cmdlist->data[cmdlist->last++] = G2D_START_BITBLT;
1217
1218        /* head */
1219        cmdlist->head = cmdlist->last / 2;
1220
1221        /* tail */
1222        cmdlist->data[cmdlist->last] = 0;
1223
1224        g2d_add_cmdlist_to_inuse(g2d_priv, node);
1225
1226        return 0;
1227
1228err_unmap:
1229        g2d_unmap_cmdlist_gem(g2d, node, file);
1230err_free_event:
1231        if (node->event) {
1232                spin_lock_irqsave(&drm_dev->event_lock, flags);
1233                file->event_space += sizeof(e->event);
1234                spin_unlock_irqrestore(&drm_dev->event_lock, flags);
1235                kfree(node->event);
1236        }
1237err:
1238        g2d_put_cmdlist(g2d, node);
1239        return ret;
1240}
1241EXPORT_SYMBOL_GPL(exynos_g2d_set_cmdlist_ioctl);
1242
1243int exynos_g2d_exec_ioctl(struct drm_device *drm_dev, void *data,
1244                          struct drm_file *file)
1245{
1246        struct drm_exynos_file_private *file_priv = file->driver_priv;
1247        struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
1248        struct device *dev;
1249        struct g2d_data *g2d;
1250        struct drm_exynos_g2d_exec *req = data;
1251        struct g2d_runqueue_node *runqueue_node;
1252        struct list_head *run_cmdlist;
1253        struct list_head *event_list;
1254
1255        if (!g2d_priv)
1256                return -ENODEV;
1257
1258        dev = g2d_priv->dev;
1259        if (!dev)
1260                return -ENODEV;
1261
1262        g2d = dev_get_drvdata(dev);
1263        if (!g2d)
1264                return -EFAULT;
1265
1266        runqueue_node = kmem_cache_alloc(g2d->runqueue_slab, GFP_KERNEL);
1267        if (!runqueue_node) {
1268                dev_err(dev, "failed to allocate memory\n");
1269                return -ENOMEM;
1270        }
1271        run_cmdlist = &runqueue_node->run_cmdlist;
1272        event_list = &runqueue_node->event_list;
1273        INIT_LIST_HEAD(run_cmdlist);
1274        INIT_LIST_HEAD(event_list);
1275        init_completion(&runqueue_node->complete);
1276        runqueue_node->async = req->async;
1277
1278        list_splice_init(&g2d_priv->inuse_cmdlist, run_cmdlist);
1279        list_splice_init(&g2d_priv->event_list, event_list);
1280
1281        if (list_empty(run_cmdlist)) {
1282                dev_err(dev, "there is no inuse cmdlist\n");
1283                kmem_cache_free(g2d->runqueue_slab, runqueue_node);
1284                return -EPERM;
1285        }
1286
1287        mutex_lock(&g2d->runqueue_mutex);
1288        runqueue_node->pid = current->pid;
1289        runqueue_node->filp = file;
1290        list_add_tail(&runqueue_node->list, &g2d->runqueue);
1291        if (!g2d->runqueue_node)
1292                g2d_exec_runqueue(g2d);
1293        mutex_unlock(&g2d->runqueue_mutex);
1294
1295        if (runqueue_node->async)
1296                goto out;
1297
1298        wait_for_completion(&runqueue_node->complete);
1299        g2d_free_runqueue_node(g2d, runqueue_node);
1300
1301out:
1302        return 0;
1303}
1304EXPORT_SYMBOL_GPL(exynos_g2d_exec_ioctl);
1305
1306static int g2d_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
1307{
1308        struct g2d_data *g2d;
1309        int ret;
1310
1311        g2d = dev_get_drvdata(dev);
1312        if (!g2d)
1313                return -EFAULT;
1314
1315        /* allocate dma-aware cmdlist buffer. */
1316        ret = g2d_init_cmdlist(g2d);
1317        if (ret < 0) {
1318                dev_err(dev, "cmdlist init failed\n");
1319                return ret;
1320        }
1321
1322        if (!is_drm_iommu_supported(drm_dev))
1323                return 0;
1324
1325        ret = drm_iommu_attach_device(drm_dev, dev);
1326        if (ret < 0) {
1327                dev_err(dev, "failed to enable iommu.\n");
1328                g2d_fini_cmdlist(g2d);
1329        }
1330
1331        return ret;
1332
1333}
1334
1335static void g2d_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
1336{
1337        if (!is_drm_iommu_supported(drm_dev))
1338                return;
1339
1340        drm_iommu_detach_device(drm_dev, dev);
1341}
1342
1343static int g2d_open(struct drm_device *drm_dev, struct device *dev,
1344                        struct drm_file *file)
1345{
1346        struct drm_exynos_file_private *file_priv = file->driver_priv;
1347        struct exynos_drm_g2d_private *g2d_priv;
1348
1349        g2d_priv = kzalloc(sizeof(*g2d_priv), GFP_KERNEL);
1350        if (!g2d_priv)
1351                return -ENOMEM;
1352
1353        g2d_priv->dev = dev;
1354        file_priv->g2d_priv = g2d_priv;
1355
1356        INIT_LIST_HEAD(&g2d_priv->inuse_cmdlist);
1357        INIT_LIST_HEAD(&g2d_priv->event_list);
1358        INIT_LIST_HEAD(&g2d_priv->userptr_list);
1359
1360        return 0;
1361}
1362
1363static void g2d_close(struct drm_device *drm_dev, struct device *dev,
1364                        struct drm_file *file)
1365{
1366        struct drm_exynos_file_private *file_priv = file->driver_priv;
1367        struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
1368        struct g2d_data *g2d;
1369        struct g2d_cmdlist_node *node, *n;
1370
1371        if (!dev)
1372                return;
1373
1374        g2d = dev_get_drvdata(dev);
1375        if (!g2d)
1376                return;
1377
1378        mutex_lock(&g2d->cmdlist_mutex);
1379        list_for_each_entry_safe(node, n, &g2d_priv->inuse_cmdlist, list) {
1380                /*
1381                 * unmap all gem objects not completed.
1382                 *
1383                 * P.S. if current process was terminated forcely then
1384                 * there may be some commands in inuse_cmdlist so unmap
1385                 * them.
1386                 */
1387                g2d_unmap_cmdlist_gem(g2d, node, file);
1388                list_move_tail(&node->list, &g2d->free_cmdlist);
1389        }
1390        mutex_unlock(&g2d->cmdlist_mutex);
1391
1392        /* release all g2d_userptr in pool. */
1393        g2d_userptr_free_all(drm_dev, g2d, file);
1394
1395        kfree(file_priv->g2d_priv);
1396}
1397
1398static int g2d_probe(struct platform_device *pdev)
1399{
1400        struct device *dev = &pdev->dev;
1401        struct resource *res;
1402        struct g2d_data *g2d;
1403        struct exynos_drm_subdrv *subdrv;
1404        int ret;
1405
1406        g2d = devm_kzalloc(dev, sizeof(*g2d), GFP_KERNEL);
1407        if (!g2d)
1408                return -ENOMEM;
1409
1410        g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",
1411                        sizeof(struct g2d_runqueue_node), 0, 0, NULL);
1412        if (!g2d->runqueue_slab)
1413                return -ENOMEM;
1414
1415        g2d->dev = dev;
1416
1417        g2d->g2d_workq = create_singlethread_workqueue("g2d");
1418        if (!g2d->g2d_workq) {
1419                dev_err(dev, "failed to create workqueue\n");
1420                ret = -EINVAL;
1421                goto err_destroy_slab;
1422        }
1423
1424        INIT_WORK(&g2d->runqueue_work, g2d_runqueue_worker);
1425        INIT_LIST_HEAD(&g2d->free_cmdlist);
1426        INIT_LIST_HEAD(&g2d->runqueue);
1427
1428        mutex_init(&g2d->cmdlist_mutex);
1429        mutex_init(&g2d->runqueue_mutex);
1430
1431        g2d->gate_clk = devm_clk_get(dev, "fimg2d");
1432        if (IS_ERR(g2d->gate_clk)) {
1433                dev_err(dev, "failed to get gate clock\n");
1434                ret = PTR_ERR(g2d->gate_clk);
1435                goto err_destroy_workqueue;
1436        }
1437
1438        pm_runtime_enable(dev);
1439
1440        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1441
1442        g2d->regs = devm_ioremap_resource(dev, res);
1443        if (IS_ERR(g2d->regs)) {
1444                ret = PTR_ERR(g2d->regs);
1445                goto err_put_clk;
1446        }
1447
1448        g2d->irq = platform_get_irq(pdev, 0);
1449        if (g2d->irq < 0) {
1450                dev_err(dev, "failed to get irq\n");
1451                ret = g2d->irq;
1452                goto err_put_clk;
1453        }
1454
1455        ret = devm_request_irq(dev, g2d->irq, g2d_irq_handler, 0,
1456                                                                "drm_g2d", g2d);
1457        if (ret < 0) {
1458                dev_err(dev, "irq request failed\n");
1459                goto err_put_clk;
1460        }
1461
1462        g2d->max_pool = MAX_POOL;
1463
1464        platform_set_drvdata(pdev, g2d);
1465
1466        subdrv = &g2d->subdrv;
1467        subdrv->dev = dev;
1468        subdrv->probe = g2d_subdrv_probe;
1469        subdrv->remove = g2d_subdrv_remove;
1470        subdrv->open = g2d_open;
1471        subdrv->close = g2d_close;
1472
1473        ret = exynos_drm_subdrv_register(subdrv);
1474        if (ret < 0) {
1475                dev_err(dev, "failed to register drm g2d device\n");
1476                goto err_put_clk;
1477        }
1478
1479        dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n",
1480                        G2D_HW_MAJOR_VER, G2D_HW_MINOR_VER);
1481
1482        return 0;
1483
1484err_put_clk:
1485        pm_runtime_disable(dev);
1486err_destroy_workqueue:
1487        destroy_workqueue(g2d->g2d_workq);
1488err_destroy_slab:
1489        kmem_cache_destroy(g2d->runqueue_slab);
1490        return ret;
1491}
1492
1493static int g2d_remove(struct platform_device *pdev)
1494{
1495        struct g2d_data *g2d = platform_get_drvdata(pdev);
1496
1497        cancel_work_sync(&g2d->runqueue_work);
1498        exynos_drm_subdrv_unregister(&g2d->subdrv);
1499
1500        while (g2d->runqueue_node) {
1501                g2d_free_runqueue_node(g2d, g2d->runqueue_node);
1502                g2d->runqueue_node = g2d_get_runqueue_node(g2d);
1503        }
1504
1505        pm_runtime_disable(&pdev->dev);
1506
1507        g2d_fini_cmdlist(g2d);
1508        destroy_workqueue(g2d->g2d_workq);
1509        kmem_cache_destroy(g2d->runqueue_slab);
1510
1511        return 0;
1512}
1513
1514#ifdef CONFIG_PM_SLEEP
1515static int g2d_suspend(struct device *dev)
1516{
1517        struct g2d_data *g2d = dev_get_drvdata(dev);
1518
1519        mutex_lock(&g2d->runqueue_mutex);
1520        g2d->suspended = true;
1521        mutex_unlock(&g2d->runqueue_mutex);
1522
1523        while (g2d->runqueue_node)
1524                /* FIXME: good range? */
1525                usleep_range(500, 1000);
1526
1527        flush_work(&g2d->runqueue_work);
1528
1529        return 0;
1530}
1531
1532static int g2d_resume(struct device *dev)
1533{
1534        struct g2d_data *g2d = dev_get_drvdata(dev);
1535
1536        g2d->suspended = false;
1537        g2d_exec_runqueue(g2d);
1538
1539        return 0;
1540}
1541#endif
1542
1543#ifdef CONFIG_PM
1544static int g2d_runtime_suspend(struct device *dev)
1545{
1546        struct g2d_data *g2d = dev_get_drvdata(dev);
1547
1548        clk_disable_unprepare(g2d->gate_clk);
1549
1550        return 0;
1551}
1552
1553static int g2d_runtime_resume(struct device *dev)
1554{
1555        struct g2d_data *g2d = dev_get_drvdata(dev);
1556        int ret;
1557
1558        ret = clk_prepare_enable(g2d->gate_clk);
1559        if (ret < 0)
1560                dev_warn(dev, "failed to enable clock.\n");
1561
1562        return ret;
1563}
1564#endif
1565
1566static const struct dev_pm_ops g2d_pm_ops = {
1567        SET_SYSTEM_SLEEP_PM_OPS(g2d_suspend, g2d_resume)
1568        SET_RUNTIME_PM_OPS(g2d_runtime_suspend, g2d_runtime_resume, NULL)
1569};
1570
1571static const struct of_device_id exynos_g2d_match[] = {
1572        { .compatible = "samsung,exynos5250-g2d" },
1573        { .compatible = "samsung,exynos4212-g2d" },
1574        {},
1575};
1576MODULE_DEVICE_TABLE(of, exynos_g2d_match);
1577
1578struct platform_driver g2d_driver = {
1579        .probe          = g2d_probe,
1580        .remove         = g2d_remove,
1581        .driver         = {
1582                .name   = "s5p-g2d",
1583                .owner  = THIS_MODULE,
1584                .pm     = &g2d_pm_ops,
1585                .of_match_table = exynos_g2d_match,
1586        },
1587};
1588