Lines Matching full:g2d
262 static inline void g2d_hw_reset(struct g2d_data *g2d) in g2d_hw_reset() argument
264 writel(G2D_R | G2D_SFRCLEAR, g2d->regs + G2D_SOFT_RESET); in g2d_hw_reset()
265 clear_bit(G2D_BIT_ENGINE_BUSY, &g2d->flags); in g2d_hw_reset()
268 static int g2d_init_cmdlist(struct g2d_data *g2d) in g2d_init_cmdlist() argument
270 struct device *dev = g2d->dev; in g2d_init_cmdlist()
276 g2d->cmdlist_dma_attrs = DMA_ATTR_WRITE_COMBINE; in g2d_init_cmdlist()
278 g2d->cmdlist_pool_virt = dma_alloc_attrs(to_dma_dev(g2d->drm_dev), in g2d_init_cmdlist()
280 &g2d->cmdlist_pool, GFP_KERNEL, in g2d_init_cmdlist()
281 g2d->cmdlist_dma_attrs); in g2d_init_cmdlist()
282 if (!g2d->cmdlist_pool_virt) { in g2d_init_cmdlist()
297 g2d->cmdlist_pool_virt + nr * G2D_CMDLIST_SIZE; in g2d_init_cmdlist()
299 g2d->cmdlist_pool + nr * G2D_CMDLIST_SIZE; in g2d_init_cmdlist()
305 list_add_tail(&node[nr].list, &g2d->free_cmdlist); in g2d_init_cmdlist()
311 dma_free_attrs(to_dma_dev(g2d->drm_dev), G2D_CMDLIST_POOL_SIZE, in g2d_init_cmdlist()
312 g2d->cmdlist_pool_virt, in g2d_init_cmdlist()
313 g2d->cmdlist_pool, g2d->cmdlist_dma_attrs); in g2d_init_cmdlist()
317 static void g2d_fini_cmdlist(struct g2d_data *g2d) in g2d_fini_cmdlist() argument
319 kfree(g2d->cmdlist_node); in g2d_fini_cmdlist()
321 if (g2d->cmdlist_pool_virt && g2d->cmdlist_pool) { in g2d_fini_cmdlist()
322 dma_free_attrs(to_dma_dev(g2d->drm_dev), in g2d_fini_cmdlist()
324 g2d->cmdlist_pool_virt, in g2d_fini_cmdlist()
325 g2d->cmdlist_pool, g2d->cmdlist_dma_attrs); in g2d_fini_cmdlist()
329 static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d) in g2d_get_cmdlist() argument
331 struct device *dev = g2d->dev; in g2d_get_cmdlist()
334 mutex_lock(&g2d->cmdlist_mutex); in g2d_get_cmdlist()
335 if (list_empty(&g2d->free_cmdlist)) { in g2d_get_cmdlist()
337 mutex_unlock(&g2d->cmdlist_mutex); in g2d_get_cmdlist()
341 node = list_first_entry(&g2d->free_cmdlist, struct g2d_cmdlist_node, in g2d_get_cmdlist()
344 mutex_unlock(&g2d->cmdlist_mutex); in g2d_get_cmdlist()
349 static void g2d_put_cmdlist(struct g2d_data *g2d, struct g2d_cmdlist_node *node) in g2d_put_cmdlist() argument
351 mutex_lock(&g2d->cmdlist_mutex); in g2d_put_cmdlist()
352 list_move_tail(&node->list, &g2d->free_cmdlist); in g2d_put_cmdlist()
353 mutex_unlock(&g2d->cmdlist_mutex); in g2d_put_cmdlist()
376 static void g2d_userptr_put_dma_addr(struct g2d_data *g2d, in g2d_userptr_put_dma_addr() argument
398 dma_unmap_sgtable(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt, in g2d_userptr_put_dma_addr()
419 static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d, in g2d_userptr_get_dma_addr() argument
433 DRM_DEV_ERROR(g2d->dev, "invalid userptr size.\n"); in g2d_userptr_get_dma_addr()
452 * at this moment, maybe g2d dma is accessing this in g2d_userptr_get_dma_addr()
486 DRM_DEV_ERROR(g2d->dev, in g2d_userptr_get_dma_addr()
508 DRM_DEV_ERROR(g2d->dev, "failed to get sgt from pages.\n"); in g2d_userptr_get_dma_addr()
514 ret = dma_map_sgtable(to_dma_dev(g2d->drm_dev), sgt, in g2d_userptr_get_dma_addr()
517 DRM_DEV_ERROR(g2d->dev, "failed to map sgt with dma region.\n"); in g2d_userptr_get_dma_addr()
526 if (g2d->current_pool + (npages << PAGE_SHIFT) < g2d->max_pool) { in g2d_userptr_get_dma_addr()
527 g2d->current_pool += npages << PAGE_SHIFT; in g2d_userptr_get_dma_addr()
553 static void g2d_userptr_free_all(struct g2d_data *g2d, struct drm_file *filp) in g2d_userptr_free_all() argument
560 g2d_userptr_put_dma_addr(g2d, g2d_userptr, true); in g2d_userptr_free_all()
562 g2d->current_pool = 0; in g2d_userptr_free_all()
565 static enum g2d_reg_type g2d_get_reg_type(struct g2d_data *g2d, int reg_offset) in g2d_get_reg_type() argument
598 DRM_DEV_ERROR(g2d->dev, "Unknown register offset![%d]\n", in g2d_get_reg_type()
633 static bool g2d_check_buf_desc_is_valid(struct g2d_data *g2d, in g2d_check_buf_desc_is_valid() argument
651 DRM_DEV_ERROR(g2d->dev, "width[%d] is out of range!\n", width); in g2d_check_buf_desc_is_valid()
658 DRM_DEV_ERROR(g2d->dev, in g2d_check_buf_desc_is_valid()
678 DRM_DEV_ERROR(g2d->dev, "last engine access position [%lu] " in g2d_check_buf_desc_is_valid()
686 static int g2d_map_cmdlist_gem(struct g2d_data *g2d, in g2d_map_cmdlist_gem() argument
709 reg_type = g2d_get_reg_type(g2d, offset); in g2d_map_cmdlist_gem()
726 if (!g2d_check_buf_desc_is_valid(g2d, buf_desc, in g2d_map_cmdlist_gem()
744 if (!g2d_check_buf_desc_is_valid(g2d, buf_desc, in g2d_map_cmdlist_gem()
751 addr = g2d_userptr_get_dma_addr(g2d, in g2d_map_cmdlist_gem()
773 static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, in g2d_unmap_cmdlist_gem() argument
793 g2d_userptr_put_dma_addr(g2d, obj, false); in g2d_unmap_cmdlist_gem()
804 static void g2d_dma_start(struct g2d_data *g2d, in g2d_dma_start() argument
811 set_bit(G2D_BIT_ENGINE_BUSY, &g2d->flags); in g2d_dma_start()
812 writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR); in g2d_dma_start()
813 writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND); in g2d_dma_start()
816 static struct g2d_runqueue_node *g2d_get_runqueue_node(struct g2d_data *g2d) in g2d_get_runqueue_node() argument
820 if (list_empty(&g2d->runqueue)) in g2d_get_runqueue_node()
823 runqueue_node = list_first_entry(&g2d->runqueue, in g2d_get_runqueue_node()
829 static void g2d_free_runqueue_node(struct g2d_data *g2d, in g2d_free_runqueue_node() argument
834 mutex_lock(&g2d->cmdlist_mutex); in g2d_free_runqueue_node()
840 g2d_unmap_cmdlist_gem(g2d, node, runqueue_node->filp); in g2d_free_runqueue_node()
841 list_splice_tail_init(&runqueue_node->run_cmdlist, &g2d->free_cmdlist); in g2d_free_runqueue_node()
842 mutex_unlock(&g2d->cmdlist_mutex); in g2d_free_runqueue_node()
844 kmem_cache_free(g2d->runqueue_slab, runqueue_node); in g2d_free_runqueue_node()
849 * @g2d: G2D state object
854 static void g2d_remove_runqueue_nodes(struct g2d_data *g2d, struct drm_file *file) in g2d_remove_runqueue_nodes() argument
858 if (list_empty(&g2d->runqueue)) in g2d_remove_runqueue_nodes()
861 list_for_each_entry_safe(node, n, &g2d->runqueue, list) { in g2d_remove_runqueue_nodes()
866 g2d_free_runqueue_node(g2d, node); in g2d_remove_runqueue_nodes()
872 struct g2d_data *g2d = container_of(work, struct g2d_data, in g2d_runqueue_worker() local
880 if (test_bit(G2D_BIT_ENGINE_BUSY, &g2d->flags)) in g2d_runqueue_worker()
883 mutex_lock(&g2d->runqueue_mutex); in g2d_runqueue_worker()
885 runqueue_node = g2d->runqueue_node; in g2d_runqueue_worker()
886 g2d->runqueue_node = NULL; in g2d_runqueue_worker()
889 pm_runtime_mark_last_busy(g2d->dev); in g2d_runqueue_worker()
890 pm_runtime_put_autosuspend(g2d->dev); in g2d_runqueue_worker()
894 g2d_free_runqueue_node(g2d, runqueue_node); in g2d_runqueue_worker()
897 if (!test_bit(G2D_BIT_SUSPEND_RUNQUEUE, &g2d->flags)) { in g2d_runqueue_worker()
898 g2d->runqueue_node = g2d_get_runqueue_node(g2d); in g2d_runqueue_worker()
900 if (g2d->runqueue_node) { in g2d_runqueue_worker()
901 pm_runtime_get_sync(g2d->dev); in g2d_runqueue_worker()
902 g2d_dma_start(g2d, g2d->runqueue_node); in g2d_runqueue_worker()
906 mutex_unlock(&g2d->runqueue_mutex); in g2d_runqueue_worker()
909 static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no) in g2d_finish_event() argument
911 struct drm_device *drm_dev = g2d->drm_dev; in g2d_finish_event()
912 struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node; in g2d_finish_event()
932 struct g2d_data *g2d = dev_id; in g2d_irq_handler() local
935 pending = readl_relaxed(g2d->regs + G2D_INTC_PEND); in g2d_irq_handler()
937 writel_relaxed(pending, g2d->regs + G2D_INTC_PEND); in g2d_irq_handler()
940 u32 cmdlist_no = readl_relaxed(g2d->regs + G2D_DMA_STATUS); in g2d_irq_handler()
945 g2d_finish_event(g2d, cmdlist_no); in g2d_irq_handler()
947 writel_relaxed(0, g2d->regs + G2D_DMA_HOLD_CMD); in g2d_irq_handler()
950 g2d->regs + G2D_DMA_COMMAND); in g2d_irq_handler()
955 clear_bit(G2D_BIT_ENGINE_BUSY, &g2d->flags); in g2d_irq_handler()
956 queue_work(g2d->g2d_workq, &g2d->runqueue_work); in g2d_irq_handler()
963 * g2d_wait_finish - wait for the G2D engine to finish the current runqueue node
964 * @g2d: G2D state object
971 static void g2d_wait_finish(struct g2d_data *g2d, struct drm_file *file) in g2d_wait_finish() argument
973 struct device *dev = g2d->dev; in g2d_wait_finish()
978 mutex_lock(&g2d->runqueue_mutex); in g2d_wait_finish()
981 if (!g2d->runqueue_node) in g2d_wait_finish()
984 runqueue_node = g2d->runqueue_node; in g2d_wait_finish()
990 mutex_unlock(&g2d->runqueue_mutex); in g2d_wait_finish()
992 /* Wait for the G2D engine to finish. */ in g2d_wait_finish()
993 while (tries-- && (g2d->runqueue_node == runqueue_node)) in g2d_wait_finish()
996 mutex_lock(&g2d->runqueue_mutex); in g2d_wait_finish()
998 if (g2d->runqueue_node != runqueue_node) in g2d_wait_finish()
1002 g2d_hw_reset(g2d); in g2d_wait_finish()
1014 g2d_free_runqueue_node(g2d, runqueue_node); in g2d_wait_finish()
1017 mutex_unlock(&g2d->runqueue_mutex); in g2d_wait_finish()
1020 static int g2d_check_reg_offset(struct g2d_data *g2d, in g2d_check_reg_offset() argument
1053 reg_type = g2d_get_reg_type(g2d, reg_offset); in g2d_check_reg_offset()
1067 reg_type = g2d_get_reg_type(g2d, reg_offset); in g2d_check_reg_offset()
1077 reg_type = g2d_get_reg_type(g2d, reg_offset); in g2d_check_reg_offset()
1089 reg_type = g2d_get_reg_type(g2d, reg_offset); in g2d_check_reg_offset()
1102 reg_type = g2d_get_reg_type(g2d, reg_offset); in g2d_check_reg_offset()
1120 dev_err(g2d->dev, "Bad register offset: 0x%lx\n", cmdlist->data[index]); in g2d_check_reg_offset()
1141 struct g2d_data *g2d = dev_get_drvdata(priv->g2d_dev); in exynos_g2d_set_cmdlist_ioctl() local
1150 node = g2d_get_cmdlist(g2d); in exynos_g2d_set_cmdlist_ioctl()
1157 * sufficient for all conceivable usage cases of the G2D. in exynos_g2d_set_cmdlist_ioctl()
1161 dev_err(g2d->dev, "number of submitted G2D commands exceeds limit\n"); in exynos_g2d_set_cmdlist_ioctl()
1193 * values of previous cmdlist. G2D hw executes SFR clear command and in exynos_g2d_set_cmdlist_ioctl()
1206 * G2D interrupt event once current command list execution is in exynos_g2d_set_cmdlist_ioctl()
1229 dev_err(g2d->dev, "cmdlist size is too big\n"); in exynos_g2d_set_cmdlist_ioctl()
1244 ret = g2d_check_reg_offset(g2d, node, req->cmd_nr, false); in exynos_g2d_set_cmdlist_ioctl()
1263 ret = g2d_check_reg_offset(g2d, node, req->cmd_buf_nr, true); in exynos_g2d_set_cmdlist_ioctl()
1267 ret = g2d_map_cmdlist_gem(g2d, node, drm_dev, file); in exynos_g2d_set_cmdlist_ioctl()
1286 g2d_unmap_cmdlist_gem(g2d, node, file); in exynos_g2d_set_cmdlist_ioctl()
1291 g2d_put_cmdlist(g2d, node); in exynos_g2d_set_cmdlist_ioctl()
1300 struct g2d_data *g2d = dev_get_drvdata(priv->g2d_dev); in exynos_g2d_exec_ioctl() local
1306 runqueue_node = kmem_cache_alloc(g2d->runqueue_slab, GFP_KERNEL); in exynos_g2d_exec_ioctl()
1321 dev_err(g2d->dev, "there is no inuse cmdlist\n"); in exynos_g2d_exec_ioctl()
1322 kmem_cache_free(g2d->runqueue_slab, runqueue_node); in exynos_g2d_exec_ioctl()
1326 mutex_lock(&g2d->runqueue_mutex); in exynos_g2d_exec_ioctl()
1329 list_add_tail(&runqueue_node->list, &g2d->runqueue); in exynos_g2d_exec_ioctl()
1330 mutex_unlock(&g2d->runqueue_mutex); in exynos_g2d_exec_ioctl()
1333 queue_work(g2d->g2d_workq, &g2d->runqueue_work); in exynos_g2d_exec_ioctl()
1339 g2d_free_runqueue_node(g2d, runqueue_node); in exynos_g2d_exec_ioctl()
1360 struct g2d_data *g2d; in g2d_close() local
1366 g2d = dev_get_drvdata(priv->g2d_dev); in g2d_close()
1369 mutex_lock(&g2d->runqueue_mutex); in g2d_close()
1370 g2d_remove_runqueue_nodes(g2d, file); in g2d_close()
1371 mutex_unlock(&g2d->runqueue_mutex); in g2d_close()
1378 g2d_wait_finish(g2d, file); in g2d_close()
1386 mutex_lock(&g2d->cmdlist_mutex); in g2d_close()
1388 g2d_unmap_cmdlist_gem(g2d, node, file); in g2d_close()
1389 list_move_tail(&node->list, &g2d->free_cmdlist); in g2d_close()
1391 mutex_unlock(&g2d->cmdlist_mutex); in g2d_close()
1394 g2d_userptr_free_all(g2d, file); in g2d_close()
1399 struct g2d_data *g2d = dev_get_drvdata(dev); in g2d_bind() local
1404 g2d->drm_dev = drm_dev; in g2d_bind()
1407 ret = g2d_init_cmdlist(g2d); in g2d_bind()
1413 ret = exynos_drm_register_dma(drm_dev, dev, &g2d->dma_priv); in g2d_bind()
1416 g2d_fini_cmdlist(g2d); in g2d_bind()
1421 dev_info(dev, "The Exynos G2D (ver %d.%d) successfully registered.\n", in g2d_bind()
1428 struct g2d_data *g2d = dev_get_drvdata(dev); in g2d_unbind() local
1433 set_bit(G2D_BIT_SUSPEND_RUNQUEUE, &g2d->flags); in g2d_unbind()
1434 g2d_wait_finish(g2d, NULL); in g2d_unbind()
1437 cancel_work_sync(&g2d->runqueue_work); in g2d_unbind()
1438 exynos_drm_unregister_dma(g2d->drm_dev, dev, &g2d->dma_priv); in g2d_unbind()
1450 struct g2d_data *g2d; in g2d_probe() local
1453 g2d = devm_kzalloc(dev, sizeof(*g2d), GFP_KERNEL); in g2d_probe()
1454 if (!g2d) in g2d_probe()
1457 g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", in g2d_probe()
1459 if (!g2d->runqueue_slab) in g2d_probe()
1462 g2d->dev = dev; in g2d_probe()
1464 g2d->g2d_workq = create_singlethread_workqueue("g2d"); in g2d_probe()
1465 if (!g2d->g2d_workq) { in g2d_probe()
1471 INIT_WORK(&g2d->runqueue_work, g2d_runqueue_worker); in g2d_probe()
1472 INIT_LIST_HEAD(&g2d->free_cmdlist); in g2d_probe()
1473 INIT_LIST_HEAD(&g2d->runqueue); in g2d_probe()
1475 mutex_init(&g2d->cmdlist_mutex); in g2d_probe()
1476 mutex_init(&g2d->runqueue_mutex); in g2d_probe()
1478 g2d->gate_clk = devm_clk_get(dev, "fimg2d"); in g2d_probe()
1479 if (IS_ERR(g2d->gate_clk)) { in g2d_probe()
1481 ret = PTR_ERR(g2d->gate_clk); in g2d_probe()
1488 clear_bit(G2D_BIT_SUSPEND_RUNQUEUE, &g2d->flags); in g2d_probe()
1489 clear_bit(G2D_BIT_ENGINE_BUSY, &g2d->flags); in g2d_probe()
1493 g2d->regs = devm_ioremap_resource(dev, res); in g2d_probe()
1494 if (IS_ERR(g2d->regs)) { in g2d_probe()
1495 ret = PTR_ERR(g2d->regs); in g2d_probe()
1499 g2d->irq = platform_get_irq(pdev, 0); in g2d_probe()
1500 if (g2d->irq < 0) { in g2d_probe()
1501 ret = g2d->irq; in g2d_probe()
1505 ret = devm_request_irq(dev, g2d->irq, g2d_irq_handler, 0, in g2d_probe()
1506 "drm_g2d", g2d); in g2d_probe()
1512 g2d->max_pool = MAX_POOL; in g2d_probe()
1514 platform_set_drvdata(pdev, g2d); in g2d_probe()
1518 dev_err(dev, "failed to register drm g2d device\n"); in g2d_probe()
1527 destroy_workqueue(g2d->g2d_workq); in g2d_probe()
1529 kmem_cache_destroy(g2d->runqueue_slab); in g2d_probe()
1535 struct g2d_data *g2d = platform_get_drvdata(pdev); in g2d_remove() local
1540 g2d_remove_runqueue_nodes(g2d, NULL); in g2d_remove()
1545 g2d_fini_cmdlist(g2d); in g2d_remove()
1546 destroy_workqueue(g2d->g2d_workq); in g2d_remove()
1547 kmem_cache_destroy(g2d->runqueue_slab); in g2d_remove()
1555 struct g2d_data *g2d = dev_get_drvdata(dev); in g2d_suspend() local
1558 * Suspend the runqueue worker operation and wait until the G2D in g2d_suspend()
1561 set_bit(G2D_BIT_SUSPEND_RUNQUEUE, &g2d->flags); in g2d_suspend()
1562 g2d_wait_finish(g2d, NULL); in g2d_suspend()
1563 flush_work(&g2d->runqueue_work); in g2d_suspend()
1570 struct g2d_data *g2d = dev_get_drvdata(dev); in g2d_resume() local
1572 clear_bit(G2D_BIT_SUSPEND_RUNQUEUE, &g2d->flags); in g2d_resume()
1573 queue_work(g2d->g2d_workq, &g2d->runqueue_work); in g2d_resume()
1582 struct g2d_data *g2d = dev_get_drvdata(dev); in g2d_runtime_suspend() local
1584 clk_disable_unprepare(g2d->gate_clk); in g2d_runtime_suspend()
1591 struct g2d_data *g2d = dev_get_drvdata(dev); in g2d_runtime_resume() local
1594 ret = clk_prepare_enable(g2d->gate_clk); in g2d_runtime_resume()
1608 { .compatible = "samsung,exynos5250-g2d" },
1609 { .compatible = "samsung,exynos4212-g2d" },
1618 .name = "exynos-drm-g2d",