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 "drmP.h" 22 #include "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 pid_t pid; 126 struct completion complete; 127 int async; 128 }; 129 130 struct g2d_data { 131 struct device *dev; 132 struct clk *gate_clk; 133 void __iomem *regs; 134 int irq; 135 struct workqueue_struct *g2d_workq; 136 struct work_struct runqueue_work; 137 struct exynos_drm_subdrv subdrv; 138 bool suspended; 139 140 /* cmdlist */ 141 struct g2d_cmdlist_node *cmdlist_node; 142 struct list_head free_cmdlist; 143 struct mutex cmdlist_mutex; 144 dma_addr_t cmdlist_pool; 145 void *cmdlist_pool_virt; 146 147 /* runqueue*/ 148 struct g2d_runqueue_node *runqueue_node; 149 struct list_head runqueue; 150 struct mutex runqueue_mutex; 151 struct kmem_cache *runqueue_slab; 152 }; 153 154 static int g2d_init_cmdlist(struct g2d_data *g2d) 155 { 156 struct device *dev = g2d->dev; 157 struct g2d_cmdlist_node *node = g2d->cmdlist_node; 158 int nr; 159 int ret; 160 161 g2d->cmdlist_pool_virt = dma_alloc_coherent(dev, G2D_CMDLIST_POOL_SIZE, 162 &g2d->cmdlist_pool, GFP_KERNEL); 163 if (!g2d->cmdlist_pool_virt) { 164 dev_err(dev, "failed to allocate dma memory\n"); 165 return -ENOMEM; 166 } 167 168 node = kcalloc(G2D_CMDLIST_NUM, sizeof(*node), 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 runqueue_node->pid = current->pid; 683 list_add_tail(&runqueue_node->list, &g2d->runqueue); 684 if (!g2d->runqueue_node) 685 g2d_exec_runqueue(g2d); 686 mutex_unlock(&g2d->runqueue_mutex); 687 688 if (runqueue_node->async) 689 goto out; 690 691 wait_for_completion(&runqueue_node->complete); 692 g2d_free_runqueue_node(g2d, runqueue_node); 693 694 out: 695 return 0; 696 } 697 EXPORT_SYMBOL_GPL(exynos_g2d_exec_ioctl); 698 699 static int g2d_open(struct drm_device *drm_dev, struct device *dev, 700 struct drm_file *file) 701 { 702 struct drm_exynos_file_private *file_priv = file->driver_priv; 703 struct exynos_drm_g2d_private *g2d_priv; 704 705 g2d_priv = kzalloc(sizeof(*g2d_priv), GFP_KERNEL); 706 if (!g2d_priv) { 707 dev_err(dev, "failed to allocate g2d private data\n"); 708 return -ENOMEM; 709 } 710 711 g2d_priv->dev = dev; 712 file_priv->g2d_priv = g2d_priv; 713 714 INIT_LIST_HEAD(&g2d_priv->inuse_cmdlist); 715 INIT_LIST_HEAD(&g2d_priv->event_list); 716 INIT_LIST_HEAD(&g2d_priv->gem_list); 717 718 return 0; 719 } 720 721 static void g2d_close(struct drm_device *drm_dev, struct device *dev, 722 struct drm_file *file) 723 { 724 struct drm_exynos_file_private *file_priv = file->driver_priv; 725 struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv; 726 struct g2d_data *g2d; 727 struct g2d_cmdlist_node *node, *n; 728 729 if (!dev) 730 return; 731 732 g2d = dev_get_drvdata(dev); 733 if (!g2d) 734 return; 735 736 mutex_lock(&g2d->cmdlist_mutex); 737 list_for_each_entry_safe(node, n, &g2d_priv->inuse_cmdlist, list) 738 list_move_tail(&node->list, &g2d->free_cmdlist); 739 mutex_unlock(&g2d->cmdlist_mutex); 740 741 g2d_put_cmdlist_gem(drm_dev, file, g2d_priv->gem_nr); 742 743 kfree(file_priv->g2d_priv); 744 } 745 746 static int __devinit g2d_probe(struct platform_device *pdev) 747 { 748 struct device *dev = &pdev->dev; 749 struct resource *res; 750 struct g2d_data *g2d; 751 struct exynos_drm_subdrv *subdrv; 752 int ret; 753 754 g2d = devm_kzalloc(&pdev->dev, sizeof(*g2d), GFP_KERNEL); 755 if (!g2d) { 756 dev_err(dev, "failed to allocate driver data\n"); 757 return -ENOMEM; 758 } 759 760 g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", 761 sizeof(struct g2d_runqueue_node), 0, 0, NULL); 762 if (!g2d->runqueue_slab) 763 return -ENOMEM; 764 765 g2d->dev = dev; 766 767 g2d->g2d_workq = create_singlethread_workqueue("g2d"); 768 if (!g2d->g2d_workq) { 769 dev_err(dev, "failed to create workqueue\n"); 770 ret = -EINVAL; 771 goto err_destroy_slab; 772 } 773 774 INIT_WORK(&g2d->runqueue_work, g2d_runqueue_worker); 775 INIT_LIST_HEAD(&g2d->free_cmdlist); 776 INIT_LIST_HEAD(&g2d->runqueue); 777 778 mutex_init(&g2d->cmdlist_mutex); 779 mutex_init(&g2d->runqueue_mutex); 780 781 ret = g2d_init_cmdlist(g2d); 782 if (ret < 0) 783 goto err_destroy_workqueue; 784 785 g2d->gate_clk = clk_get(dev, "fimg2d"); 786 if (IS_ERR(g2d->gate_clk)) { 787 dev_err(dev, "failed to get gate clock\n"); 788 ret = PTR_ERR(g2d->gate_clk); 789 goto err_fini_cmdlist; 790 } 791 792 pm_runtime_enable(dev); 793 794 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 795 796 g2d->regs = devm_request_and_ioremap(&pdev->dev, res); 797 if (!g2d->regs) { 798 dev_err(dev, "failed to remap I/O memory\n"); 799 ret = -ENXIO; 800 goto err_put_clk; 801 } 802 803 g2d->irq = platform_get_irq(pdev, 0); 804 if (g2d->irq < 0) { 805 dev_err(dev, "failed to get irq\n"); 806 ret = g2d->irq; 807 goto err_put_clk; 808 } 809 810 ret = devm_request_irq(&pdev->dev, g2d->irq, g2d_irq_handler, 0, 811 "drm_g2d", g2d); 812 if (ret < 0) { 813 dev_err(dev, "irq request failed\n"); 814 goto err_put_clk; 815 } 816 817 platform_set_drvdata(pdev, g2d); 818 819 subdrv = &g2d->subdrv; 820 subdrv->dev = dev; 821 subdrv->open = g2d_open; 822 subdrv->close = g2d_close; 823 824 ret = exynos_drm_subdrv_register(subdrv); 825 if (ret < 0) { 826 dev_err(dev, "failed to register drm g2d device\n"); 827 goto err_put_clk; 828 } 829 830 dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", 831 G2D_HW_MAJOR_VER, G2D_HW_MINOR_VER); 832 833 return 0; 834 835 err_put_clk: 836 pm_runtime_disable(dev); 837 clk_put(g2d->gate_clk); 838 err_fini_cmdlist: 839 g2d_fini_cmdlist(g2d); 840 err_destroy_workqueue: 841 destroy_workqueue(g2d->g2d_workq); 842 err_destroy_slab: 843 kmem_cache_destroy(g2d->runqueue_slab); 844 return ret; 845 } 846 847 static int __devexit g2d_remove(struct platform_device *pdev) 848 { 849 struct g2d_data *g2d = platform_get_drvdata(pdev); 850 851 cancel_work_sync(&g2d->runqueue_work); 852 exynos_drm_subdrv_unregister(&g2d->subdrv); 853 854 while (g2d->runqueue_node) { 855 g2d_free_runqueue_node(g2d, g2d->runqueue_node); 856 g2d->runqueue_node = g2d_get_runqueue_node(g2d); 857 } 858 859 pm_runtime_disable(&pdev->dev); 860 clk_put(g2d->gate_clk); 861 862 g2d_fini_cmdlist(g2d); 863 destroy_workqueue(g2d->g2d_workq); 864 kmem_cache_destroy(g2d->runqueue_slab); 865 866 return 0; 867 } 868 869 #ifdef CONFIG_PM_SLEEP 870 static int g2d_suspend(struct device *dev) 871 { 872 struct g2d_data *g2d = dev_get_drvdata(dev); 873 874 mutex_lock(&g2d->runqueue_mutex); 875 g2d->suspended = true; 876 mutex_unlock(&g2d->runqueue_mutex); 877 878 while (g2d->runqueue_node) 879 /* FIXME: good range? */ 880 usleep_range(500, 1000); 881 882 flush_work_sync(&g2d->runqueue_work); 883 884 return 0; 885 } 886 887 static int g2d_resume(struct device *dev) 888 { 889 struct g2d_data *g2d = dev_get_drvdata(dev); 890 891 g2d->suspended = false; 892 g2d_exec_runqueue(g2d); 893 894 return 0; 895 } 896 #endif 897 898 static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); 899 900 struct platform_driver g2d_driver = { 901 .probe = g2d_probe, 902 .remove = __devexit_p(g2d_remove), 903 .driver = { 904 .name = "s5p-g2d", 905 .owner = THIS_MODULE, 906 .pm = &g2d_pm_ops, 907 }, 908 }; 909