X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fgpu%2Fdrm%2Frockchip%2Frockchip_drm_rga.c;h=95da17bbb983bc688f9d6fc61712d40f636f29f5;hb=ef2c18d22821f77ecca22f62da8ae466817b809e;hp=4334c220c94f9c594412db088e7ffb6719a3f142;hpb=7b2f394bb8ae3881aed47728d8d74a9e094badd8;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_rga.c b/drivers/gpu/drm/rockchip/rockchip_drm_rga.c index 4334c220c94f..95da17bbb983 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_rga.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_rga.c @@ -51,16 +51,6 @@ static void __user *rga_compat_ptr(u64 value) #endif } -static void rga_dma_flush_range(void *ptr, int size) -{ -#ifdef CONFIG_ARM - dmac_flush_range(ptr, ptr + size); - outer_flush_range(virt_to_phys(ptr), virt_to_phys(ptr + size)); -#elif defined CONFIG_ARM64 - __dma_flush_range(ptr, ptr + size); -#endif -} - static inline void rga_write(struct rockchip_rga *rga, u32 reg, u32 value) { writel(value, rga->regs + reg); @@ -196,7 +186,9 @@ static int rga_alloc_dma_buf_for_cmdlist(struct rga_runqueue_node *runqueue) dest[reg >> 2] = mmu_ctrl; } - rga_dma_flush_range(cmdlist_pool_virt, cmdlist_cnt * RGA_CMDLIST_SIZE); + dma_sync_single_for_device(runqueue->drm_dev->dev, + virt_to_phys(cmdlist_pool_virt), + PAGE_SIZE, DMA_TO_DEVICE); runqueue->cmdlist_dma_attrs = cmdlist_dma_attrs; runqueue->cmdlist_pool_virt = cmdlist_pool_virt; @@ -221,10 +213,12 @@ static int rga_check_reg_offset(struct device *dev, switch (reg) { case RGA_BUF_TYPE_GEMFD | RGA_DST_Y_RGB_BASE_ADDR: case RGA_BUF_TYPE_GEMFD | RGA_SRC_Y_RGB_BASE_ADDR: + case RGA_BUF_TYPE_GEMFD | RGA_SRC1_RGB_BASE_ADDR: break; case RGA_BUF_TYPE_USERPTR | RGA_DST_Y_RGB_BASE_ADDR: case RGA_BUF_TYPE_USERPTR | RGA_SRC_Y_RGB_BASE_ADDR: + case RGA_BUF_TYPE_USERPTR | RGA_SRC1_RGB_BASE_ADDR: goto err; default: @@ -289,16 +283,15 @@ rga_gem_buf_to_pages(struct rockchip_rga *rga, void **mmu_pages, int fd) for (p = 0; p < len; p++) { dma_addr_t phys = address + (p << PAGE_SHIFT); - void *virt = phys_to_virt(phys); - rga_dma_flush_range(virt, 4 * 1024); pages[mapped_size + p] = phys; } mapped_size += len; } - rga_dma_flush_range(pages, 32 * 1024); + dma_sync_single_for_device(rga->drm_dev->dev, virt_to_phys(pages), + 8 * PAGE_SIZE, DMA_TO_DEVICE); *mmu_pages = pages; @@ -329,6 +322,16 @@ static int rga_map_cmdlist_gem(struct rockchip_rga *rga, int index = cmdlist->last - 2 * (i + 1); switch (cmdlist->data[index]) { + case RGA_SRC1_RGB_BASE_ADDR | RGA_BUF_TYPE_GEMFD: + fd = cmdlist->data[index + 1]; + attach = rga_gem_buf_to_pages(rga, &mmu_pages, fd); + if (IS_ERR(attach)) + return PTR_ERR(attach); + + cmdlist->src1_attach = attach; + cmdlist->src1_mmu_pages = mmu_pages; + break; + case RGA_SRC_Y_RGB_BASE_ADDR | RGA_BUF_TYPE_GEMFD: fd = cmdlist->data[index + 1]; attach = rga_gem_buf_to_pages(rga, &mmu_pages, fd); @@ -368,6 +371,14 @@ static void rga_unmap_cmdlist_gem(struct rockchip_rga *rga, } node->cmdlist.src_attach = NULL; + attach = node->cmdlist.src1_attach; + if (attach) { + dma_buf = attach->dmabuf; + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); + } + node->cmdlist.src1_attach = NULL; + attach = node->cmdlist.dst_attach; if (attach) { dma_buf = attach->dmabuf; @@ -639,6 +650,7 @@ int rockchip_rga_exec_ioctl(struct drm_device *drm_dev, void *data, return -ENOMEM; } + runqueue->drm_dev = drm_dev; runqueue->dev = rga->dev; init_completion(&runqueue->complete); @@ -678,6 +690,10 @@ static int rockchip_rga_open(struct drm_device *drm_dev, struct device *dev, { struct rockchip_drm_file_private *file_priv = file->driver_priv; struct rockchip_drm_rga_private *rga_priv; + struct rockchip_rga *rga; + + rga = dev_get_drvdata(dev); + rga->drm_dev = drm_dev; rga_priv = kzalloc(sizeof(*rga_priv), GFP_KERNEL); if (!rga_priv) @@ -845,7 +861,7 @@ static int rga_probe(struct platform_device *pdev) rga->rga_workq = create_singlethread_workqueue("rga"); if (!rga->rga_workq) { dev_err(rga->dev, "failed to create workqueue\n"); - ret = PTR_ERR(rga->rga_workq); + ret = -ENOMEM; goto err_destroy_slab; }