Lines Matching refs:g2d
250 static int g2d_init_cmdlist(struct g2d_data *g2d) in g2d_init_cmdlist() argument
252 struct device *dev = g2d->dev; in g2d_init_cmdlist()
253 struct g2d_cmdlist_node *node = g2d->cmdlist_node; in g2d_init_cmdlist()
254 struct exynos_drm_subdrv *subdrv = &g2d->subdrv; in g2d_init_cmdlist()
259 init_dma_attrs(&g2d->cmdlist_dma_attrs); in g2d_init_cmdlist()
260 dma_set_attr(DMA_ATTR_WRITE_COMBINE, &g2d->cmdlist_dma_attrs); in g2d_init_cmdlist()
262 g2d->cmdlist_pool_virt = dma_alloc_attrs(subdrv->drm_dev->dev, in g2d_init_cmdlist()
264 &g2d->cmdlist_pool, GFP_KERNEL, in g2d_init_cmdlist()
265 &g2d->cmdlist_dma_attrs); in g2d_init_cmdlist()
266 if (!g2d->cmdlist_pool_virt) { in g2d_init_cmdlist()
282 g2d->cmdlist_pool_virt + nr * G2D_CMDLIST_SIZE; in g2d_init_cmdlist()
284 g2d->cmdlist_pool + nr * G2D_CMDLIST_SIZE; in g2d_init_cmdlist()
290 list_add_tail(&node[nr].list, &g2d->free_cmdlist); in g2d_init_cmdlist()
297 g2d->cmdlist_pool_virt, in g2d_init_cmdlist()
298 g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs); in g2d_init_cmdlist()
302 static void g2d_fini_cmdlist(struct g2d_data *g2d) in g2d_fini_cmdlist() argument
304 struct exynos_drm_subdrv *subdrv = &g2d->subdrv; in g2d_fini_cmdlist()
306 kfree(g2d->cmdlist_node); in g2d_fini_cmdlist()
308 if (g2d->cmdlist_pool_virt && g2d->cmdlist_pool) { in g2d_fini_cmdlist()
310 g2d->cmdlist_pool_virt, in g2d_fini_cmdlist()
311 g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs); in g2d_fini_cmdlist()
315 static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d) in g2d_get_cmdlist() argument
317 struct device *dev = g2d->dev; in g2d_get_cmdlist()
320 mutex_lock(&g2d->cmdlist_mutex); in g2d_get_cmdlist()
321 if (list_empty(&g2d->free_cmdlist)) { in g2d_get_cmdlist()
323 mutex_unlock(&g2d->cmdlist_mutex); in g2d_get_cmdlist()
327 node = list_first_entry(&g2d->free_cmdlist, struct g2d_cmdlist_node, in g2d_get_cmdlist()
330 mutex_unlock(&g2d->cmdlist_mutex); in g2d_get_cmdlist()
335 static void g2d_put_cmdlist(struct g2d_data *g2d, struct g2d_cmdlist_node *node) in g2d_put_cmdlist() argument
337 mutex_lock(&g2d->cmdlist_mutex); in g2d_put_cmdlist()
338 list_move_tail(&node->list, &g2d->free_cmdlist); in g2d_put_cmdlist()
339 mutex_unlock(&g2d->cmdlist_mutex); in g2d_put_cmdlist()
415 struct g2d_data *g2d; in g2d_userptr_get_dma_addr() local
426 g2d = dev_get_drvdata(g2d_priv->dev); in g2d_userptr_get_dma_addr()
515 if (g2d->current_pool + (npages << PAGE_SHIFT) < g2d->max_pool) { in g2d_userptr_get_dma_addr()
516 g2d->current_pool += npages << PAGE_SHIFT; in g2d_userptr_get_dma_addr()
543 struct g2d_data *g2d, in g2d_userptr_free_all() argument
556 g2d->current_pool = 0; in g2d_userptr_free_all()
677 static int g2d_map_cmdlist_gem(struct g2d_data *g2d, in g2d_map_cmdlist_gem() argument
767 static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, in g2d_unmap_cmdlist_gem() argument
771 struct exynos_drm_subdrv *subdrv = &g2d->subdrv; in g2d_unmap_cmdlist_gem()
801 static void g2d_dma_start(struct g2d_data *g2d, in g2d_dma_start() argument
809 ret = pm_runtime_get_sync(g2d->dev); in g2d_dma_start()
813 writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR); in g2d_dma_start()
814 writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND); in g2d_dma_start()
817 static struct g2d_runqueue_node *g2d_get_runqueue_node(struct g2d_data *g2d) in g2d_get_runqueue_node() argument
821 if (list_empty(&g2d->runqueue)) in g2d_get_runqueue_node()
824 runqueue_node = list_first_entry(&g2d->runqueue, in g2d_get_runqueue_node()
830 static void g2d_free_runqueue_node(struct g2d_data *g2d, in g2d_free_runqueue_node() argument
838 mutex_lock(&g2d->cmdlist_mutex); in g2d_free_runqueue_node()
844 g2d_unmap_cmdlist_gem(g2d, node, runqueue_node->filp); in g2d_free_runqueue_node()
845 list_splice_tail_init(&runqueue_node->run_cmdlist, &g2d->free_cmdlist); in g2d_free_runqueue_node()
846 mutex_unlock(&g2d->cmdlist_mutex); in g2d_free_runqueue_node()
848 kmem_cache_free(g2d->runqueue_slab, runqueue_node); in g2d_free_runqueue_node()
851 static void g2d_exec_runqueue(struct g2d_data *g2d) in g2d_exec_runqueue() argument
853 g2d->runqueue_node = g2d_get_runqueue_node(g2d); in g2d_exec_runqueue()
854 if (g2d->runqueue_node) in g2d_exec_runqueue()
855 g2d_dma_start(g2d, g2d->runqueue_node); in g2d_exec_runqueue()
860 struct g2d_data *g2d = container_of(work, struct g2d_data, in g2d_runqueue_worker() local
863 mutex_lock(&g2d->runqueue_mutex); in g2d_runqueue_worker()
864 pm_runtime_put_sync(g2d->dev); in g2d_runqueue_worker()
866 complete(&g2d->runqueue_node->complete); in g2d_runqueue_worker()
867 if (g2d->runqueue_node->async) in g2d_runqueue_worker()
868 g2d_free_runqueue_node(g2d, g2d->runqueue_node); in g2d_runqueue_worker()
870 if (g2d->suspended) in g2d_runqueue_worker()
871 g2d->runqueue_node = NULL; in g2d_runqueue_worker()
873 g2d_exec_runqueue(g2d); in g2d_runqueue_worker()
874 mutex_unlock(&g2d->runqueue_mutex); in g2d_runqueue_worker()
877 static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no) in g2d_finish_event() argument
879 struct drm_device *drm_dev = g2d->subdrv.drm_dev; in g2d_finish_event()
880 struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node; in g2d_finish_event()
904 struct g2d_data *g2d = dev_id; in g2d_irq_handler() local
907 pending = readl_relaxed(g2d->regs + G2D_INTC_PEND); in g2d_irq_handler()
909 writel_relaxed(pending, g2d->regs + G2D_INTC_PEND); in g2d_irq_handler()
912 u32 cmdlist_no = readl_relaxed(g2d->regs + G2D_DMA_STATUS); in g2d_irq_handler()
917 g2d_finish_event(g2d, cmdlist_no); in g2d_irq_handler()
919 writel_relaxed(0, g2d->regs + G2D_DMA_HOLD_CMD); in g2d_irq_handler()
922 g2d->regs + G2D_DMA_COMMAND); in g2d_irq_handler()
927 queue_work(g2d->g2d_workq, &g2d->runqueue_work); in g2d_irq_handler()
1043 struct g2d_data *g2d; in exynos_g2d_get_ver_ioctl() local
1053 g2d = dev_get_drvdata(dev); in exynos_g2d_get_ver_ioctl()
1054 if (!g2d) in exynos_g2d_get_ver_ioctl()
1069 struct g2d_data *g2d; in exynos_g2d_set_cmdlist_ioctl() local
1086 g2d = dev_get_drvdata(dev); in exynos_g2d_set_cmdlist_ioctl()
1087 if (!g2d) in exynos_g2d_set_cmdlist_ioctl()
1090 node = g2d_get_cmdlist(g2d); in exynos_g2d_set_cmdlist_ioctl()
1201 ret = g2d_map_cmdlist_gem(g2d, node, drm_dev, file); in exynos_g2d_set_cmdlist_ioctl()
1220 g2d_unmap_cmdlist_gem(g2d, node, file); in exynos_g2d_set_cmdlist_ioctl()
1229 g2d_put_cmdlist(g2d, node); in exynos_g2d_set_cmdlist_ioctl()
1239 struct g2d_data *g2d; in exynos_g2d_exec_ioctl() local
1252 g2d = dev_get_drvdata(dev); in exynos_g2d_exec_ioctl()
1253 if (!g2d) in exynos_g2d_exec_ioctl()
1256 runqueue_node = kmem_cache_alloc(g2d->runqueue_slab, GFP_KERNEL); in exynos_g2d_exec_ioctl()
1273 kmem_cache_free(g2d->runqueue_slab, runqueue_node); in exynos_g2d_exec_ioctl()
1277 mutex_lock(&g2d->runqueue_mutex); in exynos_g2d_exec_ioctl()
1280 list_add_tail(&runqueue_node->list, &g2d->runqueue); in exynos_g2d_exec_ioctl()
1281 if (!g2d->runqueue_node) in exynos_g2d_exec_ioctl()
1282 g2d_exec_runqueue(g2d); in exynos_g2d_exec_ioctl()
1283 mutex_unlock(&g2d->runqueue_mutex); in exynos_g2d_exec_ioctl()
1289 g2d_free_runqueue_node(g2d, runqueue_node); in exynos_g2d_exec_ioctl()
1297 struct g2d_data *g2d; in g2d_subdrv_probe() local
1300 g2d = dev_get_drvdata(dev); in g2d_subdrv_probe()
1301 if (!g2d) in g2d_subdrv_probe()
1305 ret = g2d_init_cmdlist(g2d); in g2d_subdrv_probe()
1314 g2d_fini_cmdlist(g2d); in g2d_subdrv_probe()
1351 struct g2d_data *g2d; in g2d_close() local
1357 g2d = dev_get_drvdata(dev); in g2d_close()
1358 if (!g2d) in g2d_close()
1361 mutex_lock(&g2d->cmdlist_mutex); in g2d_close()
1370 g2d_unmap_cmdlist_gem(g2d, node, file); in g2d_close()
1371 list_move_tail(&node->list, &g2d->free_cmdlist); in g2d_close()
1373 mutex_unlock(&g2d->cmdlist_mutex); in g2d_close()
1376 g2d_userptr_free_all(drm_dev, g2d, file); in g2d_close()
1385 struct g2d_data *g2d; in g2d_probe() local
1389 g2d = devm_kzalloc(dev, sizeof(*g2d), GFP_KERNEL); in g2d_probe()
1390 if (!g2d) in g2d_probe()
1393 g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", in g2d_probe()
1395 if (!g2d->runqueue_slab) in g2d_probe()
1398 g2d->dev = dev; in g2d_probe()
1400 g2d->g2d_workq = create_singlethread_workqueue("g2d"); in g2d_probe()
1401 if (!g2d->g2d_workq) { in g2d_probe()
1407 INIT_WORK(&g2d->runqueue_work, g2d_runqueue_worker); in g2d_probe()
1408 INIT_LIST_HEAD(&g2d->free_cmdlist); in g2d_probe()
1409 INIT_LIST_HEAD(&g2d->runqueue); in g2d_probe()
1411 mutex_init(&g2d->cmdlist_mutex); in g2d_probe()
1412 mutex_init(&g2d->runqueue_mutex); in g2d_probe()
1414 g2d->gate_clk = devm_clk_get(dev, "fimg2d"); in g2d_probe()
1415 if (IS_ERR(g2d->gate_clk)) { in g2d_probe()
1417 ret = PTR_ERR(g2d->gate_clk); in g2d_probe()
1425 g2d->regs = devm_ioremap_resource(dev, res); in g2d_probe()
1426 if (IS_ERR(g2d->regs)) { in g2d_probe()
1427 ret = PTR_ERR(g2d->regs); in g2d_probe()
1431 g2d->irq = platform_get_irq(pdev, 0); in g2d_probe()
1432 if (g2d->irq < 0) { in g2d_probe()
1434 ret = g2d->irq; in g2d_probe()
1438 ret = devm_request_irq(dev, g2d->irq, g2d_irq_handler, 0, in g2d_probe()
1439 "drm_g2d", g2d); in g2d_probe()
1445 g2d->max_pool = MAX_POOL; in g2d_probe()
1447 platform_set_drvdata(pdev, g2d); in g2d_probe()
1449 subdrv = &g2d->subdrv; in g2d_probe()
1470 destroy_workqueue(g2d->g2d_workq); in g2d_probe()
1472 kmem_cache_destroy(g2d->runqueue_slab); in g2d_probe()
1478 struct g2d_data *g2d = platform_get_drvdata(pdev); in g2d_remove() local
1480 cancel_work_sync(&g2d->runqueue_work); in g2d_remove()
1481 exynos_drm_subdrv_unregister(&g2d->subdrv); in g2d_remove()
1483 while (g2d->runqueue_node) { in g2d_remove()
1484 g2d_free_runqueue_node(g2d, g2d->runqueue_node); in g2d_remove()
1485 g2d->runqueue_node = g2d_get_runqueue_node(g2d); in g2d_remove()
1490 g2d_fini_cmdlist(g2d); in g2d_remove()
1491 destroy_workqueue(g2d->g2d_workq); in g2d_remove()
1492 kmem_cache_destroy(g2d->runqueue_slab); in g2d_remove()
1500 struct g2d_data *g2d = dev_get_drvdata(dev); in g2d_suspend() local
1502 mutex_lock(&g2d->runqueue_mutex); in g2d_suspend()
1503 g2d->suspended = true; in g2d_suspend()
1504 mutex_unlock(&g2d->runqueue_mutex); in g2d_suspend()
1506 while (g2d->runqueue_node) in g2d_suspend()
1510 flush_work(&g2d->runqueue_work); in g2d_suspend()
1517 struct g2d_data *g2d = dev_get_drvdata(dev); in g2d_resume() local
1519 g2d->suspended = false; in g2d_resume()
1520 g2d_exec_runqueue(g2d); in g2d_resume()
1529 struct g2d_data *g2d = dev_get_drvdata(dev); in g2d_runtime_suspend() local
1531 clk_disable_unprepare(g2d->gate_clk); in g2d_runtime_suspend()
1538 struct g2d_data *g2d = dev_get_drvdata(dev); in g2d_runtime_resume() local
1541 ret = clk_prepare_enable(g2d->gate_clk); in g2d_runtime_resume()