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/module.h> 12 #include <linux/clk.h> 13 #include <linux/err.h> 14 #include <linux/interrupt.h> 15 #include <linux/io.h> 16 #include <linux/platform_device.h> 17 #include <linux/pm_runtime.h> 18 #include <linux/slab.h> 19 #include <linux/workqueue.h> 20 21 #include <drm/drmP.h> 22 #include <drm/exynos_drm.h> 23 #include "exynos_drm_drv.h" 24 #include "exynos_drm_gem.h" 25 26 #define G2D_HW_MAJOR_VER 4 27 #define G2D_HW_MINOR_VER 1 28 29 /* vaild register range set from user: 0x0104 ~ 0x0880 */ 30 #define G2D_VALID_START 0x0104 31 #define G2D_VALID_END 0x0880 32 33 /* general registers */ 34 #define G2D_SOFT_RESET 0x0000 35 #define G2D_INTEN 0x0004 36 #define G2D_INTC_PEND 0x000C 37 #define G2D_DMA_SFR_BASE_ADDR 0x0080 38 #define G2D_DMA_COMMAND 0x0084 39 #define G2D_DMA_STATUS 0x008C 40 #define G2D_DMA_HOLD_CMD 0x0090 41 42 /* command registers */ 43 #define G2D_BITBLT_START 0x0100 44 45 /* registers for base address */ 46 #define G2D_SRC_BASE_ADDR 0x0304 47 #define G2D_SRC_PLANE2_BASE_ADDR 0x0318 48 #define G2D_DST_BASE_ADDR 0x0404 49 #define G2D_DST_PLANE2_BASE_ADDR 0x0418 50 #define G2D_PAT_BASE_ADDR 0x0500 51 #define G2D_MSK_BASE_ADDR 0x0520 52 53 /* G2D_SOFT_RESET */ 54 #define G2D_SFRCLEAR (1 << 1) 55 #define G2D_R (1 << 0) 56 57 /* G2D_INTEN */ 58 #define G2D_INTEN_ACF (1 << 3) 59 #define G2D_INTEN_UCF (1 << 2) 60 #define G2D_INTEN_GCF (1 << 1) 61 #define G2D_INTEN_SCF (1 << 0) 62 63 /* G2D_INTC_PEND */ 64 #define G2D_INTP_ACMD_FIN (1 << 3) 65 #define G2D_INTP_UCMD_FIN (1 << 2) 66 #define G2D_INTP_GCMD_FIN (1 << 1) 67 #define G2D_INTP_SCMD_FIN (1 << 0) 68 69 /* G2D_DMA_COMMAND */ 70 #define G2D_DMA_HALT (1 << 2) 71 #define G2D_DMA_CONTINUE (1 << 1) 72 #define G2D_DMA_START (1 << 0) 73 74 /* G2D_DMA_STATUS */ 75 #define G2D_DMA_LIST_DONE_COUNT (0xFF << 17) 76 #define G2D_DMA_BITBLT_DONE_COUNT (0xFFFF << 1) 77 #define G2D_DMA_DONE (1 << 0) 78 #define G2D_DMA_LIST_DONE_COUNT_OFFSET 17 79 80 /* G2D_DMA_HOLD_CMD */ 81 #define G2D_USET_HOLD (1 << 2) 82 #define G2D_LIST_HOLD (1 << 1) 83 #define G2D_BITBLT_HOLD (1 << 0) 84 85 /* G2D_BITBLT_START */ 86 #define G2D_START_CASESEL (1 << 2) 87 #define G2D_START_NHOLT (1 << 1) 88 #define G2D_START_BITBLT (1 << 0) 89 90 #define G2D_CMDLIST_SIZE (PAGE_SIZE / 4) 91 #define G2D_CMDLIST_NUM 64 92 #define G2D_CMDLIST_POOL_SIZE (G2D_CMDLIST_SIZE * G2D_CMDLIST_NUM) 93 #define G2D_CMDLIST_DATA_NUM (G2D_CMDLIST_SIZE / sizeof(u32) - 2) 94 95 /* cmdlist data structure */ 96 struct g2d_cmdlist { 97 u32 head; 98 u32 data[G2D_CMDLIST_DATA_NUM]; 99 u32 last; /* last data offset */ 100 }; 101 102 struct drm_exynos_pending_g2d_event { 103 struct drm_pending_event base; 104 struct drm_exynos_g2d_event event; 105 }; 106 107 struct g2d_gem_node { 108 struct list_head list; 109 unsigned int handle; 110 }; 111 112 struct g2d_cmdlist_node { 113 struct list_head list; 114 struct g2d_cmdlist *cmdlist; 115 unsigned int gem_nr; 116 dma_addr_t dma_addr; 117 118 struct drm_exynos_pending_g2d_event *event; 119 }; 120 121 struct g2d_runqueue_node { 122 struct list_head list; 123 struct list_head run_cmdlist; 124 struct list_head event_list; 125 struct completion complete; 126 int async; 127 }; 128 129 struct g2d_data { 130 struct device *dev; 131 struct clk *gate_clk; 132 void __iomem *regs; 133 int irq; 134 struct workqueue_struct *g2d_workq; 135 struct work_struct runqueue_work; 136 struct exynos_drm_subdrv subdrv; 137 bool suspended; 138 139 /* cmdlist */ 140 struct g2d_cmdlist_node *cmdlist_node; 141 struct list_head free_cmdlist; 142 struct mutex cmdlist_mutex; 143 dma_addr_t cmdlist_pool; 144 void *cmdlist_pool_virt; 145 146 /* runqueue*/ 147 struct g2d_runqueue_node *runqueue_node; 148 struct list_head runqueue; 149 struct mutex runqueue_mutex; 150 struct kmem_cache *runqueue_slab; 151 }; 152 153 static int g2d_init_cmdlist(struct g2d_data *g2d) 154 { 155 struct device *dev = g2d->dev; 156 struct g2d_cmdlist_node *node = g2d->cmdlist_node; 157 int nr; 158 int ret; 159 160 g2d->cmdlist_pool_virt = dma_alloc_coherent(dev, G2D_CMDLIST_POOL_SIZE, 161 &g2d->cmdlist_pool, GFP_KERNEL); 162 if (!g2d->cmdlist_pool_virt) { 163 dev_err(dev, "failed to allocate dma memory\n"); 164 return -ENOMEM; 165 } 166 167 node = kcalloc(G2D_CMDLIST_NUM, G2D_CMDLIST_NUM * sizeof(*node), 168 GFP_KERNEL); 169 if (!node) { 170 dev_err(dev, "failed to allocate memory\n"); 171 ret = -ENOMEM; 172 goto err; 173 } 174 175 for (nr = 0; nr < G2D_CMDLIST_NUM; nr++) { 176 node[nr].cmdlist = 177 g2d->cmdlist_pool_virt + nr * G2D_CMDLIST_SIZE; 178 node[nr].dma_addr = 179 g2d->cmdlist_pool + nr * G2D_CMDLIST_SIZE; 180 181 list_add_tail(&node[nr].list, &g2d->free_cmdlist); 182 } 183 184 return 0; 185 186 err: 187 dma_free_coherent(dev, G2D_CMDLIST_POOL_SIZE, g2d->cmdlist_pool_virt, 188 g2d->cmdlist_pool); 189 return ret; 190 } 191 192 static void g2d_fini_cmdlist(struct g2d_data *g2d) 193 { 194 struct device *dev = g2d->dev; 195 196 kfree(g2d->cmdlist_node); 197 dma_free_coherent(dev, G2D_CMDLIST_POOL_SIZE, g2d->cmdlist_pool_virt, 198 g2d->cmdlist_pool); 199 } 200 201 static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d) 202 { 203 struct device *dev = g2d->dev; 204 struct g2d_cmdlist_node *node; 205 206 mutex_lock(&g2d->cmdlist_mutex); 207 if (list_empty(&g2d->free_cmdlist)) { 208 dev_err(dev, "there is no free cmdlist\n"); 209 mutex_unlock(&g2d->cmdlist_mutex); 210 return NULL; 211 } 212 213 node = list_first_entry(&g2d->free_cmdlist, struct g2d_cmdlist_node, 214 list); 215 list_del_init(&node->list); 216 mutex_unlock(&g2d->cmdlist_mutex); 217 218 return node; 219 } 220 221 static void g2d_put_cmdlist(struct g2d_data *g2d, struct g2d_cmdlist_node *node) 222 { 223 mutex_lock(&g2d->cmdlist_mutex); 224 list_move_tail(&node->list, &g2d->free_cmdlist); 225 mutex_unlock(&g2d->cmdlist_mutex); 226 } 227 228 static void g2d_add_cmdlist_to_inuse(struct exynos_drm_g2d_private *g2d_priv, 229 struct g2d_cmdlist_node *node) 230 { 231 struct g2d_cmdlist_node *lnode; 232 233 if (list_empty(&g2d_priv->inuse_cmdlist)) 234 goto add_to_list; 235 236 /* this links to base address of new cmdlist */ 237 lnode = list_entry(g2d_priv->inuse_cmdlist.prev, 238 struct g2d_cmdlist_node, list); 239 lnode->cmdlist->data[lnode->cmdlist->last] = node->dma_addr; 240 241 add_to_list: 242 list_add_tail(&node->list, &g2d_priv->inuse_cmdlist); 243 244 if (node->event) 245 list_add_tail(&node->event->base.link, &g2d_priv->event_list); 246 } 247 248 static int g2d_get_cmdlist_gem(struct drm_device *drm_dev, 249 struct drm_file *file, 250 struct g2d_cmdlist_node *node) 251 { 252 struct drm_exynos_file_private *file_priv = file->driver_priv; 253 struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv; 254 struct g2d_cmdlist *cmdlist = node->cmdlist; 255 dma_addr_t *addr; 256 int offset; 257 int i; 258 259 for (i = 0; i < node->gem_nr; i++) { 260 struct g2d_gem_node *gem_node; 261 262 gem_node = kzalloc(sizeof(*gem_node), GFP_KERNEL); 263 if (!gem_node) { 264 dev_err(g2d_priv->dev, "failed to allocate gem node\n"); 265 return -ENOMEM; 266 } 267 268 offset = cmdlist->last - (i * 2 + 1); 269 gem_node->handle = cmdlist->data[offset]; 270 271 addr = exynos_drm_gem_get_dma_addr(drm_dev, gem_node->handle, 272 file); 273 if (IS_ERR(addr)) { 274 node->gem_nr = i; 275 kfree(gem_node); 276 return PTR_ERR(addr); 277 } 278 279 cmdlist->data[offset] = *addr; 280 list_add_tail(&gem_node->list, &g2d_priv->gem_list); 281 g2d_priv->gem_nr++; 282 } 283 284 return 0; 285 } 286 287 static void g2d_put_cmdlist_gem(struct drm_device *drm_dev, 288 struct drm_file *file, 289 unsigned int nr) 290 { 291 struct drm_exynos_file_private *file_priv = file->driver_priv; 292 struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv; 293 struct g2d_gem_node *node, *n; 294 295 list_for_each_entry_safe_reverse(node, n, &g2d_priv->gem_list, list) { 296 if (!nr) 297 break; 298 299 exynos_drm_gem_put_dma_addr(drm_dev, node->handle, file); 300 list_del_init(&node->list); 301 kfree(node); 302 nr--; 303 } 304 } 305 306 static void g2d_dma_start(struct g2d_data *g2d, 307 struct g2d_runqueue_node *runqueue_node) 308 { 309 struct g2d_cmdlist_node *node = 310 list_first_entry(&runqueue_node->run_cmdlist, 311 struct g2d_cmdlist_node, list); 312 313 pm_runtime_get_sync(g2d->dev); 314 clk_enable(g2d->gate_clk); 315 316 /* interrupt enable */ 317 writel_relaxed(G2D_INTEN_ACF | G2D_INTEN_UCF | G2D_INTEN_GCF, 318 g2d->regs + G2D_INTEN); 319 320 writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR); 321 writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND); 322 } 323 324 static struct g2d_runqueue_node *g2d_get_runqueue_node(struct g2d_data *g2d) 325 { 326 struct g2d_runqueue_node *runqueue_node; 327 328 if (list_empty(&g2d->runqueue)) 329 return NULL; 330 331 runqueue_node = list_first_entry(&g2d->runqueue, 332 struct g2d_runqueue_node, list); 333 list_del_init(&runqueue_node->list); 334 return runqueue_node; 335 } 336 337 static void g2d_free_runqueue_node(struct g2d_data *g2d, 338 struct g2d_runqueue_node *runqueue_node) 339 { 340 if (!runqueue_node) 341 return; 342 343 mutex_lock(&g2d->cmdlist_mutex); 344 list_splice_tail_init(&runqueue_node->run_cmdlist, &g2d->free_cmdlist); 345 mutex_unlock(&g2d->cmdlist_mutex); 346 347 kmem_cache_free(g2d->runqueue_slab, runqueue_node); 348 } 349 350 static void g2d_exec_runqueue(struct g2d_data *g2d) 351 { 352 g2d->runqueue_node = g2d_get_runqueue_node(g2d); 353 if (g2d->runqueue_node) 354 g2d_dma_start(g2d, g2d->runqueue_node); 355 } 356 357 static void g2d_runqueue_worker(struct work_struct *work) 358 { 359 struct g2d_data *g2d = container_of(work, struct g2d_data, 360 runqueue_work); 361 362 363 mutex_lock(&g2d->runqueue_mutex); 364 clk_disable(g2d->gate_clk); 365 pm_runtime_put_sync(g2d->dev); 366 367 complete(&g2d->runqueue_node->complete); 368 if (g2d->runqueue_node->async) 369 g2d_free_runqueue_node(g2d, g2d->runqueue_node); 370 371 if (g2d->suspended) 372 g2d->runqueue_node = NULL; 373 else 374 g2d_exec_runqueue(g2d); 375 mutex_unlock(&g2d->runqueue_mutex); 376 } 377 378 static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no) 379 { 380 struct drm_device *drm_dev = g2d->subdrv.drm_dev; 381 struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node; 382 struct drm_exynos_pending_g2d_event *e; 383 struct timeval now; 384 unsigned long flags; 385 386 if (list_empty(&runqueue_node->event_list)) 387 return; 388 389 e = list_first_entry(&runqueue_node->event_list, 390 struct drm_exynos_pending_g2d_event, base.link); 391 392 do_gettimeofday(&now); 393 e->event.tv_sec = now.tv_sec; 394 e->event.tv_usec = now.tv_usec; 395 e->event.cmdlist_no = cmdlist_no; 396 397 spin_lock_irqsave(&drm_dev->event_lock, flags); 398 list_move_tail(&e->base.link, &e->base.file_priv->event_list); 399 wake_up_interruptible(&e->base.file_priv->event_wait); 400 spin_unlock_irqrestore(&drm_dev->event_lock, flags); 401 } 402 403 static irqreturn_t g2d_irq_handler(int irq, void *dev_id) 404 { 405 struct g2d_data *g2d = dev_id; 406 u32 pending; 407 408 pending = readl_relaxed(g2d->regs + G2D_INTC_PEND); 409 if (pending) 410 writel_relaxed(pending, g2d->regs + G2D_INTC_PEND); 411 412 if (pending & G2D_INTP_GCMD_FIN) { 413 u32 cmdlist_no = readl_relaxed(g2d->regs + G2D_DMA_STATUS); 414 415 cmdlist_no = (cmdlist_no & G2D_DMA_LIST_DONE_COUNT) >> 416 G2D_DMA_LIST_DONE_COUNT_OFFSET; 417 418 g2d_finish_event(g2d, cmdlist_no); 419 420 writel_relaxed(0, g2d->regs + G2D_DMA_HOLD_CMD); 421 if (!(pending & G2D_INTP_ACMD_FIN)) { 422 writel_relaxed(G2D_DMA_CONTINUE, 423 g2d->regs + G2D_DMA_COMMAND); 424 } 425 } 426 427 if (pending & G2D_INTP_ACMD_FIN) 428 queue_work(g2d->g2d_workq, &g2d->runqueue_work); 429 430 return IRQ_HANDLED; 431 } 432 433 static int g2d_check_reg_offset(struct device *dev, struct g2d_cmdlist *cmdlist, 434 int nr, bool for_addr) 435 { 436 int reg_offset; 437 int index; 438 int i; 439 440 for (i = 0; i < nr; i++) { 441 index = cmdlist->last - 2 * (i + 1); 442 reg_offset = cmdlist->data[index] & ~0xfffff000; 443 444 if (reg_offset < G2D_VALID_START || reg_offset > G2D_VALID_END) 445 goto err; 446 if (reg_offset % 4) 447 goto err; 448 449 switch (reg_offset) { 450 case G2D_SRC_BASE_ADDR: 451 case G2D_SRC_PLANE2_BASE_ADDR: 452 case G2D_DST_BASE_ADDR: 453 case G2D_DST_PLANE2_BASE_ADDR: 454 case G2D_PAT_BASE_ADDR: 455 case G2D_MSK_BASE_ADDR: 456 if (!for_addr) 457 goto err; 458 break; 459 default: 460 if (for_addr) 461 goto err; 462 break; 463 } 464 } 465 466 return 0; 467 468 err: 469 dev_err(dev, "Bad register offset: 0x%x\n", cmdlist->data[index]); 470 return -EINVAL; 471 } 472 473 /* ioctl functions */ 474 int exynos_g2d_get_ver_ioctl(struct drm_device *drm_dev, void *data, 475 struct drm_file *file) 476 { 477 struct drm_exynos_g2d_get_ver *ver = data; 478 479 ver->major = G2D_HW_MAJOR_VER; 480 ver->minor = G2D_HW_MINOR_VER; 481 482 return 0; 483 } 484 EXPORT_SYMBOL_GPL(exynos_g2d_get_ver_ioctl); 485 486 int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, 487 struct drm_file *file) 488 { 489 struct drm_exynos_file_private *file_priv = file->driver_priv; 490 struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv; 491 struct device *dev = g2d_priv->dev; 492 struct g2d_data *g2d; 493 struct drm_exynos_g2d_set_cmdlist *req = data; 494 struct drm_exynos_g2d_cmd *cmd; 495 struct drm_exynos_pending_g2d_event *e; 496 struct g2d_cmdlist_node *node; 497 struct g2d_cmdlist *cmdlist; 498 unsigned long flags; 499 int size; 500 int ret; 501 502 if (!dev) 503 return -ENODEV; 504 505 g2d = dev_get_drvdata(dev); 506 if (!g2d) 507 return -EFAULT; 508 509 node = g2d_get_cmdlist(g2d); 510 if (!node) 511 return -ENOMEM; 512 513 node->event = NULL; 514 515 if (req->event_type != G2D_EVENT_NOT) { 516 spin_lock_irqsave(&drm_dev->event_lock, flags); 517 if (file->event_space < sizeof(e->event)) { 518 spin_unlock_irqrestore(&drm_dev->event_lock, flags); 519 ret = -ENOMEM; 520 goto err; 521 } 522 file->event_space -= sizeof(e->event); 523 spin_unlock_irqrestore(&drm_dev->event_lock, flags); 524 525 e = kzalloc(sizeof(*node->event), GFP_KERNEL); 526 if (!e) { 527 dev_err(dev, "failed to allocate event\n"); 528 529 spin_lock_irqsave(&drm_dev->event_lock, flags); 530 file->event_space += sizeof(e->event); 531 spin_unlock_irqrestore(&drm_dev->event_lock, flags); 532 533 ret = -ENOMEM; 534 goto err; 535 } 536 537 e->event.base.type = DRM_EXYNOS_G2D_EVENT; 538 e->event.base.length = sizeof(e->event); 539 e->event.user_data = req->user_data; 540 e->base.event = &e->event.base; 541 e->base.file_priv = file; 542 e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; 543 544 node->event = e; 545 } 546 547 cmdlist = node->cmdlist; 548 549 cmdlist->last = 0; 550 551 /* 552 * If don't clear SFR registers, the cmdlist is affected by register 553 * values of previous cmdlist. G2D hw executes SFR clear command and 554 * a next command at the same time then the next command is ignored and 555 * is executed rightly from next next command, so needs a dummy command 556 * to next command of SFR clear command. 557 */ 558 cmdlist->data[cmdlist->last++] = G2D_SOFT_RESET; 559 cmdlist->data[cmdlist->last++] = G2D_SFRCLEAR; 560 cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR; 561 cmdlist->data[cmdlist->last++] = 0; 562 563 if (node->event) { 564 cmdlist->data[cmdlist->last++] = G2D_DMA_HOLD_CMD; 565 cmdlist->data[cmdlist->last++] = G2D_LIST_HOLD; 566 } 567 568 /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */ 569 size = cmdlist->last + req->cmd_nr * 2 + req->cmd_gem_nr * 2 + 2; 570 if (size > G2D_CMDLIST_DATA_NUM) { 571 dev_err(dev, "cmdlist size is too big\n"); 572 ret = -EINVAL; 573 goto err_free_event; 574 } 575 576 cmd = (struct drm_exynos_g2d_cmd *)(uint32_t)req->cmd; 577 578 if (copy_from_user(cmdlist->data + cmdlist->last, 579 (void __user *)cmd, 580 sizeof(*cmd) * req->cmd_nr)) { 581 ret = -EFAULT; 582 goto err_free_event; 583 } 584 cmdlist->last += req->cmd_nr * 2; 585 586 ret = g2d_check_reg_offset(dev, cmdlist, req->cmd_nr, false); 587 if (ret < 0) 588 goto err_free_event; 589 590 node->gem_nr = req->cmd_gem_nr; 591 if (req->cmd_gem_nr) { 592 struct drm_exynos_g2d_cmd *cmd_gem; 593 594 cmd_gem = (struct drm_exynos_g2d_cmd *)(uint32_t)req->cmd_gem; 595 596 if (copy_from_user(cmdlist->data + cmdlist->last, 597 (void __user *)cmd_gem, 598 sizeof(*cmd_gem) * req->cmd_gem_nr)) { 599 ret = -EFAULT; 600 goto err_free_event; 601 } 602 cmdlist->last += req->cmd_gem_nr * 2; 603 604 ret = g2d_check_reg_offset(dev, cmdlist, req->cmd_gem_nr, true); 605 if (ret < 0) 606 goto err_free_event; 607 608 ret = g2d_get_cmdlist_gem(drm_dev, file, node); 609 if (ret < 0) 610 goto err_unmap; 611 } 612 613 cmdlist->data[cmdlist->last++] = G2D_BITBLT_START; 614 cmdlist->data[cmdlist->last++] = G2D_START_BITBLT; 615 616 /* head */ 617 cmdlist->head = cmdlist->last / 2; 618 619 /* tail */ 620 cmdlist->data[cmdlist->last] = 0; 621 622 g2d_add_cmdlist_to_inuse(g2d_priv, node); 623 624 return 0; 625 626 err_unmap: 627 g2d_put_cmdlist_gem(drm_dev, file, node->gem_nr); 628 err_free_event: 629 if (node->event) { 630 spin_lock_irqsave(&drm_dev->event_lock, flags); 631 file->event_space += sizeof(e->event); 632 spin_unlock_irqrestore(&drm_dev->event_lock, flags); 633 kfree(node->event); 634 } 635 err: 636 g2d_put_cmdlist(g2d, node); 637 return ret; 638 } 639 EXPORT_SYMBOL_GPL(exynos_g2d_set_cmdlist_ioctl); 640 641 int exynos_g2d_exec_ioctl(struct drm_device *drm_dev, void *data, 642 struct drm_file *file) 643 { 644 struct drm_exynos_file_private *file_priv = file->driver_priv; 645 struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv; 646 struct device *dev = g2d_priv->dev; 647 struct g2d_data *g2d; 648 struct drm_exynos_g2d_exec *req = data; 649 struct g2d_runqueue_node *runqueue_node; 650 struct list_head *run_cmdlist; 651 struct list_head *event_list; 652 653 if (!dev) 654 return -ENODEV; 655 656 g2d = dev_get_drvdata(dev); 657 if (!g2d) 658 return -EFAULT; 659 660 runqueue_node = kmem_cache_alloc(g2d->runqueue_slab, GFP_KERNEL); 661 if (!runqueue_node) { 662 dev_err(dev, "failed to allocate memory\n"); 663 return -ENOMEM; 664 } 665 run_cmdlist = &runqueue_node->run_cmdlist; 666 event_list = &runqueue_node->event_list; 667 INIT_LIST_HEAD(run_cmdlist); 668 INIT_LIST_HEAD(event_list); 669 init_completion(&runqueue_node->complete); 670 runqueue_node->async = req->async; 671 672 list_splice_init(&g2d_priv->inuse_cmdlist, run_cmdlist); 673 list_splice_init(&g2d_priv->event_list, event_list); 674 675 if (list_empty(run_cmdlist)) { 676 dev_err(dev, "there is no inuse cmdlist\n"); 677 kmem_cache_free(g2d->runqueue_slab, runqueue_node); 678 return -EPERM; 679 } 680 681 mutex_lock(&g2d->runqueue_mutex); 682 list_add_tail(&runqueue_node->list, &g2d->runqueue); 683 if (!g2d->runqueue_node) 684 g2d_exec_runqueue(g2d); 685 mutex_unlock(&g2d->runqueue_mutex); 686 687 if (runqueue_node->async) 688 goto out; 689 690 wait_for_completion(&runqueue_node->complete); 691 g2d_free_runqueue_node(g2d, runqueue_node); 692 693 out: 694 return 0; 695 } 696 EXPORT_SYMBOL_GPL(exynos_g2d_exec_ioctl); 697 698 static int g2d_open(struct drm_device *drm_dev, struct device *dev, 699 struct drm_file *file) 700 { 701 struct drm_exynos_file_private *file_priv = file->driver_priv; 702 struct exynos_drm_g2d_private *g2d_priv; 703 704 g2d_priv = kzalloc(sizeof(*g2d_priv), GFP_KERNEL); 705 if (!g2d_priv) { 706 dev_err(dev, "failed to allocate g2d private data\n"); 707 return -ENOMEM; 708 } 709 710 g2d_priv->dev = dev; 711 file_priv->g2d_priv = g2d_priv; 712 713 INIT_LIST_HEAD(&g2d_priv->inuse_cmdlist); 714 INIT_LIST_HEAD(&g2d_priv->event_list); 715 INIT_LIST_HEAD(&g2d_priv->gem_list); 716 717 return 0; 718 } 719 720 static void g2d_close(struct drm_device *drm_dev, struct device *dev, 721 struct drm_file *file) 722 { 723 struct drm_exynos_file_private *file_priv = file->driver_priv; 724 struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv; 725 struct g2d_data *g2d; 726 struct g2d_cmdlist_node *node, *n; 727 728 if (!dev) 729 return; 730 731 g2d = dev_get_drvdata(dev); 732 if (!g2d) 733 return; 734 735 mutex_lock(&g2d->cmdlist_mutex); 736 list_for_each_entry_safe(node, n, &g2d_priv->inuse_cmdlist, list) 737 list_move_tail(&node->list, &g2d->free_cmdlist); 738 mutex_unlock(&g2d->cmdlist_mutex); 739 740 g2d_put_cmdlist_gem(drm_dev, file, g2d_priv->gem_nr); 741 742 kfree(file_priv->g2d_priv); 743 } 744 745 static int __devinit g2d_probe(struct platform_device *pdev) 746 { 747 struct device *dev = &pdev->dev; 748 struct resource *res; 749 struct g2d_data *g2d; 750 struct exynos_drm_subdrv *subdrv; 751 int ret; 752 753 g2d = devm_kzalloc(&pdev->dev, sizeof(*g2d), GFP_KERNEL); 754 if (!g2d) { 755 dev_err(dev, "failed to allocate driver data\n"); 756 return -ENOMEM; 757 } 758 759 g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", 760 sizeof(struct g2d_runqueue_node), 0, 0, NULL); 761 if (!g2d->runqueue_slab) 762 return -ENOMEM; 763 764 g2d->dev = dev; 765 766 g2d->g2d_workq = create_singlethread_workqueue("g2d"); 767 if (!g2d->g2d_workq) { 768 dev_err(dev, "failed to create workqueue\n"); 769 ret = -EINVAL; 770 goto err_destroy_slab; 771 } 772 773 INIT_WORK(&g2d->runqueue_work, g2d_runqueue_worker); 774 INIT_LIST_HEAD(&g2d->free_cmdlist); 775 INIT_LIST_HEAD(&g2d->runqueue); 776 777 mutex_init(&g2d->cmdlist_mutex); 778 mutex_init(&g2d->runqueue_mutex); 779 780 ret = g2d_init_cmdlist(g2d); 781 if (ret < 0) 782 goto err_destroy_workqueue; 783 784 g2d->gate_clk = clk_get(dev, "fimg2d"); 785 if (IS_ERR(g2d->gate_clk)) { 786 dev_err(dev, "failed to get gate clock\n"); 787 ret = PTR_ERR(g2d->gate_clk); 788 goto err_fini_cmdlist; 789 } 790 791 pm_runtime_enable(dev); 792 793 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 794 795 g2d->regs = devm_request_and_ioremap(&pdev->dev, res); 796 if (!g2d->regs) { 797 dev_err(dev, "failed to remap I/O memory\n"); 798 ret = -ENXIO; 799 goto err_put_clk; 800 } 801 802 g2d->irq = platform_get_irq(pdev, 0); 803 if (g2d->irq < 0) { 804 dev_err(dev, "failed to get irq\n"); 805 ret = g2d->irq; 806 goto err_put_clk; 807 } 808 809 ret = devm_request_irq(&pdev->dev, g2d->irq, g2d_irq_handler, 0, 810 "drm_g2d", g2d); 811 if (ret < 0) { 812 dev_err(dev, "irq request failed\n"); 813 goto err_put_clk; 814 } 815 816 platform_set_drvdata(pdev, g2d); 817 818 subdrv = &g2d->subdrv; 819 subdrv->dev = dev; 820 subdrv->open = g2d_open; 821 subdrv->close = g2d_close; 822 823 ret = exynos_drm_subdrv_register(subdrv); 824 if (ret < 0) { 825 dev_err(dev, "failed to register drm g2d device\n"); 826 goto err_put_clk; 827 } 828 829 dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", 830 G2D_HW_MAJOR_VER, G2D_HW_MINOR_VER); 831 832 return 0; 833 834 err_put_clk: 835 pm_runtime_disable(dev); 836 clk_put(g2d->gate_clk); 837 err_fini_cmdlist: 838 g2d_fini_cmdlist(g2d); 839 err_destroy_workqueue: 840 destroy_workqueue(g2d->g2d_workq); 841 err_destroy_slab: 842 kmem_cache_destroy(g2d->runqueue_slab); 843 return ret; 844 } 845 846 static int __devexit g2d_remove(struct platform_device *pdev) 847 { 848 struct g2d_data *g2d = platform_get_drvdata(pdev); 849 850 cancel_work_sync(&g2d->runqueue_work); 851 exynos_drm_subdrv_unregister(&g2d->subdrv); 852 853 while (g2d->runqueue_node) { 854 g2d_free_runqueue_node(g2d, g2d->runqueue_node); 855 g2d->runqueue_node = g2d_get_runqueue_node(g2d); 856 } 857 858 pm_runtime_disable(&pdev->dev); 859 clk_put(g2d->gate_clk); 860 861 g2d_fini_cmdlist(g2d); 862 destroy_workqueue(g2d->g2d_workq); 863 kmem_cache_destroy(g2d->runqueue_slab); 864 865 return 0; 866 } 867 868 #ifdef CONFIG_PM_SLEEP 869 static int g2d_suspend(struct device *dev) 870 { 871 struct g2d_data *g2d = dev_get_drvdata(dev); 872 873 mutex_lock(&g2d->runqueue_mutex); 874 g2d->suspended = true; 875 mutex_unlock(&g2d->runqueue_mutex); 876 877 while (g2d->runqueue_node) 878 /* FIXME: good range? */ 879 usleep_range(500, 1000); 880 881 flush_work_sync(&g2d->runqueue_work); 882 883 return 0; 884 } 885 886 static int g2d_resume(struct device *dev) 887 { 888 struct g2d_data *g2d = dev_get_drvdata(dev); 889 890 g2d->suspended = false; 891 g2d_exec_runqueue(g2d); 892 893 return 0; 894 } 895 #endif 896 897 static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); 898 899 struct platform_driver g2d_driver = { 900 .probe = g2d_probe, 901 .remove = __devexit_p(g2d_remove), 902 .driver = { 903 .name = "s5p-g2d", 904 .owner = THIS_MODULE, 905 .pm = &g2d_pm_ops, 906 }, 907 }; 908