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