From fdd79b0db1899f915f489e744a06846284fa3f1e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 5 Apr 2020 14:10:09 +0200 Subject: [PATCH 1/8] drm/exynos: Delete an error message in three functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function “platform_get_irq” can log an error already. Thus omit redundant messages for the exception handling in the calling functions. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 4 +--- drivers/gpu/drm/exynos/exynos_drm_rotator.c | 4 +--- drivers/gpu/drm/exynos/exynos_drm_scaler.c | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 902938d2568f9..958e2c6a6702c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1809,10 +1809,8 @@ static int exynos_dsi_probe(struct platform_device *pdev) } dsi->irq = platform_get_irq(pdev, 0); - if (dsi->irq < 0) { - dev_err(dev, "failed to request dsi irq resource\n"); + if (dsi->irq < 0) return dsi->irq; - } irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN); ret = devm_request_threaded_irq(dev, dsi->irq, NULL, diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c index dafa87b820529..2d94afba031e4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c +++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c @@ -293,10 +293,8 @@ static int rotator_probe(struct platform_device *pdev) return PTR_ERR(rot->regs); irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(dev, "failed to get irq\n"); + if (irq < 0) return irq; - } ret = devm_request_irq(dev, irq, rotator_irq_handler, 0, dev_name(dev), rot); diff --git a/drivers/gpu/drm/exynos/exynos_drm_scaler.c b/drivers/gpu/drm/exynos/exynos_drm_scaler.c index 93c43c8d914ee..ce1857138f893 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_scaler.c +++ b/drivers/gpu/drm/exynos/exynos_drm_scaler.c @@ -502,10 +502,8 @@ static int scaler_probe(struct platform_device *pdev) return PTR_ERR(scaler->regs); irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(dev, "failed to get irq\n"); + if (irq < 0) return irq; - } ret = devm_request_threaded_irq(dev, irq, NULL, scaler_irq_handler, IRQF_ONESHOT, "drm_scaler", scaler); From 3a2fe5662c5634b7b975fefd0b9c45bd35f72de8 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 7 Apr 2020 15:42:54 +0200 Subject: [PATCH 2/8] drm/exynos: gem: Remove dead-code The ExynosDRM page fault handler is never used, drm_gem_mmap() always calls exynos_drm_gem_mmap() function, which perform complete mapping for the given virtual address-space area. Signed-off-by: Marek Szyprowski Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 1 - drivers/gpu/drm/exynos/exynos_drm_gem.c | 20 -------------------- drivers/gpu/drm/exynos/exynos_drm_gem.h | 3 --- 3 files changed, 24 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 57defeb445223..dbd80f1e4c78b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -76,7 +76,6 @@ static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) } static const struct vm_operations_struct exynos_drm_gem_vm_ops = { - .fault = exynos_drm_gem_fault, .open = drm_gem_vm_open, .close = drm_gem_vm_close, }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index d734d9d51762f..40514d3dcf60f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -381,26 +381,6 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, return 0; } -vm_fault_t exynos_drm_gem_fault(struct vm_fault *vmf) -{ - struct vm_area_struct *vma = vmf->vma; - struct drm_gem_object *obj = vma->vm_private_data; - struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj); - unsigned long pfn; - pgoff_t page_offset; - - page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT; - - if (page_offset >= (exynos_gem->size >> PAGE_SHIFT)) { - DRM_ERROR("invalid page offset\n"); - return VM_FAULT_SIGBUS; - } - - pfn = page_to_pfn(exynos_gem->pages[page_offset]); - return vmf_insert_mixed(vma, vmf->address, - __pfn_to_pfn_t(pfn, PFN_DEV)); -} - static int exynos_drm_gem_mmap_obj(struct drm_gem_object *obj, struct vm_area_struct *vma) { diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index 42ec67bc262d4..f00044c0b6884 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -101,9 +101,6 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args); -/* page fault handler and mmap fault address(virtual) to physical memory. */ -vm_fault_t exynos_drm_gem_fault(struct vm_fault *vmf); - /* set vm_flags and we can change the vm attribute to other one at here. */ int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); From 24f6fe796a964f1cba75030dbea297d7fb2f30cb Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 22 Apr 2020 13:40:59 +0200 Subject: [PATCH 3/8] drm/exynos: gem: rework scatter-list contiguity check on prime import Explicitly check if the imported buffer has been mapped as contiguous in the DMA address space, what is required by all Exynos DRM CRTC drivers. While touching this, set buffer flags depending on the availability of the IOMMU. Signed-off-by: Marek Szyprowski Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 42 ++++++++++++++++++------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 40514d3dcf60f..f136efb9d1ff5 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -458,6 +458,29 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev, int npages; int ret; + if (sgt->nents < 1) + return ERR_PTR(-EINVAL); + + /* + * Check if the provided buffer has been mapped as contiguous + * into DMA address space. + */ + if (sgt->nents > 1) { + dma_addr_t next_addr = sg_dma_address(sgt->sgl); + struct scatterlist *s; + unsigned int i; + + for_each_sg(sgt->sgl, s, sgt->nents, i) { + if (!sg_dma_len(s)) + break; + if (sg_dma_address(s) != next_addr) { + DRM_ERROR("buffer chunks must be mapped contiguously"); + return ERR_PTR(-EINVAL); + } + next_addr = sg_dma_address(s) + sg_dma_len(s); + } + } + exynos_gem = exynos_drm_gem_init(dev, attach->dmabuf->size); if (IS_ERR(exynos_gem)) { ret = PTR_ERR(exynos_gem); @@ -480,18 +503,15 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev, exynos_gem->sgt = sgt; - if (sgt->nents == 1) { - /* always physically continuous memory if sgt->nents is 1. */ - exynos_gem->flags |= EXYNOS_BO_CONTIG; - } else { - /* - * this case could be CONTIG or NONCONTIG type but for now - * sets NONCONTIG. - * TODO. we have to find a way that exporter can notify - * the type of its own buffer to importer. - */ + /* + * Buffer has been mapped as contiguous into DMA address space, + * but if there is IOMMU, it can be either CONTIG or NONCONTIG. + * We assume a simplified logic below: + */ + if (is_drm_iommu_supported(dev)) exynos_gem->flags |= EXYNOS_BO_NONCONTIG; - } + else + exynos_gem->flags |= EXYNOS_BO_CONTIG; return &exynos_gem->base; From 9940d9d93406f41ad4dc69fa2cda1e059a7ca108 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 23 Apr 2020 14:43:49 +0900 Subject: [PATCH 4/8] drm/exynos: gem: Get rid of the internal 'pages' array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Internal pages array and scatter-list for them is not really needed for anything. FBDev emulation can simply rely on the DMA-mapping framework to create a proper kernel mapping for the buffer, while all other buffer use cases don't really need that array at all. Suggested-by: Christian König Signed-off-by: Marek Szyprowski Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 28 +---- drivers/gpu/drm/exynos/exynos_drm_gem.c | 124 +++++++--------------- drivers/gpu/drm/exynos/exynos_drm_gem.h | 13 +-- 3 files changed, 42 insertions(+), 123 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index e6ceaf36fb044..56a2b47e1af79 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -76,7 +76,6 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, struct fb_info *fbi; struct drm_framebuffer *fb = helper->fb; unsigned int size = fb->width * fb->height * fb->format->cpp[0]; - unsigned int nr_pages; unsigned long offset; fbi = drm_fb_helper_alloc_fbi(helper); @@ -90,16 +89,6 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, drm_fb_helper_fill_info(fbi, helper, sizes); - nr_pages = exynos_gem->size >> PAGE_SHIFT; - - exynos_gem->kvaddr = (void __iomem *) vmap(exynos_gem->pages, nr_pages, - VM_MAP, pgprot_writecombine(PAGE_KERNEL)); - if (!exynos_gem->kvaddr) { - DRM_DEV_ERROR(to_dma_dev(helper->dev), - "failed to map pages to kernel space.\n"); - return -EIO; - } - offset = fbi->var.xoffset * fb->format->cpp[0]; offset += fbi->var.yoffset * fb->pitches[0]; @@ -133,18 +122,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, size = mode_cmd.pitches[0] * mode_cmd.height; - exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG, size); - /* - * If physically contiguous memory allocation fails and if IOMMU is - * supported then try to get buffer from non physically contiguous - * memory area. - */ - if (IS_ERR(exynos_gem) && is_drm_iommu_supported(dev)) { - dev_warn(dev->dev, "contiguous FB allocation failed, falling back to non-contiguous\n"); - exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_NONCONTIG, - size); - } - + exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_WC, size, true); if (IS_ERR(exynos_gem)) return PTR_ERR(exynos_gem); @@ -229,12 +207,8 @@ int exynos_drm_fbdev_init(struct drm_device *dev) static void exynos_drm_fbdev_destroy(struct drm_device *dev, struct drm_fb_helper *fb_helper) { - struct exynos_drm_fbdev *exynos_fbd = to_exynos_fbdev(fb_helper); - struct exynos_drm_gem *exynos_gem = exynos_fbd->exynos_gem; struct drm_framebuffer *fb; - vunmap(exynos_gem->kvaddr); - /* release drm framebuffer and real buffer */ if (fb_helper->fb && fb_helper->fb->funcs) { fb = fb_helper->fb; diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index f136efb9d1ff5..0df57ee341441 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -17,28 +17,23 @@ #include "exynos_drm_drv.h" #include "exynos_drm_gem.h" -static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) +static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem, bool kvmap) { struct drm_device *dev = exynos_gem->base.dev; - unsigned long attr; - unsigned int nr_pages; - struct sg_table sgt; - int ret = -ENOMEM; + unsigned long attr = 0; if (exynos_gem->dma_addr) { DRM_DEV_DEBUG_KMS(to_dma_dev(dev), "already allocated.\n"); return 0; } - exynos_gem->dma_attrs = 0; - /* * if EXYNOS_BO_CONTIG, fully physically contiguous memory * region will be allocated else physically contiguous * as possible. */ if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG)) - exynos_gem->dma_attrs |= DMA_ATTR_FORCE_CONTIGUOUS; + attr |= DMA_ATTR_FORCE_CONTIGUOUS; /* * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping @@ -46,61 +41,29 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) */ if (exynos_gem->flags & EXYNOS_BO_WC || !(exynos_gem->flags & EXYNOS_BO_CACHABLE)) - attr = DMA_ATTR_WRITE_COMBINE; + attr |= DMA_ATTR_WRITE_COMBINE; else - attr = DMA_ATTR_NON_CONSISTENT; - - exynos_gem->dma_attrs |= attr; - exynos_gem->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING; - - nr_pages = exynos_gem->size >> PAGE_SHIFT; + attr |= DMA_ATTR_NON_CONSISTENT; - exynos_gem->pages = kvmalloc_array(nr_pages, sizeof(struct page *), - GFP_KERNEL | __GFP_ZERO); - if (!exynos_gem->pages) { - DRM_DEV_ERROR(to_dma_dev(dev), "failed to allocate pages.\n"); - return -ENOMEM; - } + /* FBDev emulation requires kernel mapping */ + if (!kvmap) + attr |= DMA_ATTR_NO_KERNEL_MAPPING; + exynos_gem->dma_attrs = attr; exynos_gem->cookie = dma_alloc_attrs(to_dma_dev(dev), exynos_gem->size, &exynos_gem->dma_addr, GFP_KERNEL, exynos_gem->dma_attrs); if (!exynos_gem->cookie) { DRM_DEV_ERROR(to_dma_dev(dev), "failed to allocate buffer.\n"); - goto err_free; - } - - ret = dma_get_sgtable_attrs(to_dma_dev(dev), &sgt, exynos_gem->cookie, - exynos_gem->dma_addr, exynos_gem->size, - exynos_gem->dma_attrs); - if (ret < 0) { - DRM_DEV_ERROR(to_dma_dev(dev), "failed to get sgtable.\n"); - goto err_dma_free; - } - - if (drm_prime_sg_to_page_addr_arrays(&sgt, exynos_gem->pages, NULL, - nr_pages)) { - DRM_DEV_ERROR(to_dma_dev(dev), "invalid sgtable.\n"); - ret = -EINVAL; - goto err_sgt_free; + return -ENOMEM; } - sg_free_table(&sgt); + if (kvmap) + exynos_gem->kvaddr = exynos_gem->cookie; DRM_DEV_DEBUG_KMS(to_dma_dev(dev), "dma_addr(0x%lx), size(0x%lx)\n", (unsigned long)exynos_gem->dma_addr, exynos_gem->size); - return 0; - -err_sgt_free: - sg_free_table(&sgt); -err_dma_free: - dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie, - exynos_gem->dma_addr, exynos_gem->dma_attrs); -err_free: - kvfree(exynos_gem->pages); - - return ret; } static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem) @@ -118,8 +81,6 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem) dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie, (dma_addr_t)exynos_gem->dma_addr, exynos_gem->dma_attrs); - - kvfree(exynos_gem->pages); } static int exynos_drm_gem_handle_create(struct drm_gem_object *obj, @@ -203,7 +164,8 @@ static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev, struct exynos_drm_gem *exynos_drm_gem_create(struct drm_device *dev, unsigned int flags, - unsigned long size) + unsigned long size, + bool kvmap) { struct exynos_drm_gem *exynos_gem; int ret; @@ -237,7 +199,7 @@ struct exynos_drm_gem *exynos_drm_gem_create(struct drm_device *dev, /* set memory type and cache attribute from user side. */ exynos_gem->flags = flags; - ret = exynos_drm_alloc_buf(exynos_gem); + ret = exynos_drm_alloc_buf(exynos_gem, kvmap); if (ret < 0) { drm_gem_object_release(&exynos_gem->base); kfree(exynos_gem); @@ -254,7 +216,7 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, struct exynos_drm_gem *exynos_gem; int ret; - exynos_gem = exynos_drm_gem_create(dev, args->flags, args->size); + exynos_gem = exynos_drm_gem_create(dev, args->flags, args->size, false); if (IS_ERR(exynos_gem)) return PTR_ERR(exynos_gem); @@ -365,7 +327,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, else flags = EXYNOS_BO_CONTIG | EXYNOS_BO_WC; - exynos_gem = exynos_drm_gem_create(dev, flags, args->size); + exynos_gem = exynos_drm_gem_create(dev, flags, args->size, false); if (IS_ERR(exynos_gem)) { dev_warn(dev->dev, "FB allocation failed.\n"); return PTR_ERR(exynos_gem); @@ -442,11 +404,24 @@ struct drm_gem_object *exynos_drm_gem_prime_import(struct drm_device *dev, struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj) { struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj); - int npages; + struct drm_device *drm_dev = obj->dev; + struct sg_table *sgt; + int ret; + + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) + return ERR_PTR(-ENOMEM); - npages = exynos_gem->size >> PAGE_SHIFT; + ret = dma_get_sgtable_attrs(to_dma_dev(drm_dev), sgt, exynos_gem->cookie, + exynos_gem->dma_addr, exynos_gem->size, + exynos_gem->dma_attrs); + if (ret) { + DRM_ERROR("failed to get sgtable, %d\n", ret); + kfree(sgt); + return ERR_PTR(ret); + } - return drm_prime_pages_to_sg(exynos_gem->pages, npages); + return sgt; } struct drm_gem_object * @@ -455,8 +430,6 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev, struct sg_table *sgt) { struct exynos_drm_gem *exynos_gem; - int npages; - int ret; if (sgt->nents < 1) return ERR_PTR(-EINVAL); @@ -482,26 +455,8 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev, } exynos_gem = exynos_drm_gem_init(dev, attach->dmabuf->size); - if (IS_ERR(exynos_gem)) { - ret = PTR_ERR(exynos_gem); - return ERR_PTR(ret); - } - - exynos_gem->dma_addr = sg_dma_address(sgt->sgl); - - npages = exynos_gem->size >> PAGE_SHIFT; - exynos_gem->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); - if (!exynos_gem->pages) { - ret = -ENOMEM; - goto err; - } - - ret = drm_prime_sg_to_page_addr_arrays(sgt, exynos_gem->pages, NULL, - npages); - if (ret < 0) - goto err_free_large; - - exynos_gem->sgt = sgt; + if (IS_ERR(exynos_gem)) + return ERR_CAST(exynos_gem); /* * Buffer has been mapped as contiguous into DMA address space, @@ -513,14 +468,9 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev, else exynos_gem->flags |= EXYNOS_BO_CONTIG; + exynos_gem->dma_addr = sg_dma_address(sgt->sgl); + exynos_gem->sgt = sgt; return &exynos_gem->base; - -err_free_large: - kvfree(exynos_gem->pages); -err: - drm_gem_object_release(&exynos_gem->base); - kfree(exynos_gem); - return ERR_PTR(ret); } void *exynos_drm_gem_prime_vmap(struct drm_gem_object *obj) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index f00044c0b6884..6ef001f890aa1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -21,20 +21,15 @@ * @base: a gem object. * - a new handle to this gem object would be created * by drm_gem_handle_create(). - * @buffer: a pointer to exynos_drm_gem_buffer object. - * - contain the information to memory region allocated - * by user request or at framebuffer creation. - * continuous memory region allocated by user request - * or at framebuffer creation. * @flags: indicate memory type to allocated buffer and cache attruibute. * @size: size requested from user, in bytes and this size is aligned * in page unit. * @cookie: cookie returned by dma_alloc_attrs - * @kvaddr: kernel virtual address to allocated memory region. + * @kvaddr: kernel virtual address to allocated memory region (for fbdev) * @dma_addr: bus address(accessed by dma) to allocated memory region. * - this address could be physical address without IOMMU and * device address with IOMMU. - * @pages: Array of backing pages. + * @dma_attrs: attrs passed dma mapping framework * @sgt: Imported sg_table. * * P.S. this object would be transferred to user as kms_bo.handle so @@ -48,7 +43,6 @@ struct exynos_drm_gem { void __iomem *kvaddr; dma_addr_t dma_addr; unsigned long dma_attrs; - struct page **pages; struct sg_table *sgt; }; @@ -58,7 +52,8 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem *exynos_gem); /* create a new buffer with gem object */ struct exynos_drm_gem *exynos_drm_gem_create(struct drm_device *dev, unsigned int flags, - unsigned long size); + unsigned long size, + bool kvmap); /* * request gem object creation and buffer allocation as the size From a046e7bf4e27d77a34595778945adbd4450d803a Mon Sep 17 00:00:00 2001 From: Bernard Zhao Date: Sun, 26 Apr 2020 02:01:42 -0700 Subject: [PATCH 5/8] drm/exynos: make pointer to const data const type Maybe keep pointer which points to global const string data in const type is better, make sure not change const data. Signed-off-by: Bernard Zhao Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 2 +- drivers/gpu/drm/exynos/exynos_drm_mic.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 958e2c6a6702c..eb1486d2dd227 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -212,7 +212,7 @@ #define OLD_SCLK_MIPI_CLK_NAME "pll_clk" -static char *clk_names[5] = { "bus_clk", "sclk_mipi", +static const char *const clk_names[5] = { "bus_clk", "sclk_mipi", "phyclk_mipidphy0_bitclkdiv8", "phyclk_mipidphy0_rxclkesc0", "sclk_rgb_vclk_to_dsim0" }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c index f41d75923557a..a86abc173605e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c @@ -88,7 +88,7 @@ #define MIC_BS_SIZE_2D(x) ((x) & 0x3fff) -static char *clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" }; +static const char *const clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" }; #define NUM_CLKS ARRAY_SIZE(clk_names) static DEFINE_MUTEX(mic_mutex); From fda022143f6f00fc4c3c296175b5e315c7c12710 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 14 May 2020 12:08:12 +0200 Subject: [PATCH 6/8] drm/exynos: mixer: Fix enabling of the runtime power management Runtime power management is essential for the Exynos Mixer driver operation. It should be enabled before adding its DRM component, because in some cases (when deferred probe takes place due to the IOMMU availability) the DRM driver might be initialized directly from the Mixer's component_add() call, what results in starting the driver operation without enabling the runtime power management. Signed-off-by: Marek Szyprowski Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 21b726baedeaa..c7e2e2ebc327b 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1244,9 +1244,11 @@ static int mixer_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ctx); + pm_runtime_enable(dev); + ret = component_add(&pdev->dev, &mixer_component_ops); - if (!ret) - pm_runtime_enable(dev); + if (ret) + pm_runtime_disable(dev); return ret; } From 547a7348633b1f9923551f94ac3157a613d2c9f2 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 16 May 2020 12:57:36 +0200 Subject: [PATCH 7/8] drm/exynos: dsi: Remove bridge node reference in error handling path in probe function 'exynos_dsi_parse_dt()' takes a reference to 'dsi->in_bridge_node'. This must be released in the error handling path. In order to do that, add an error handling path and move the 'exynos_dsi_parse_dt()' call from the beginning to the end of the probe function to ease the error handling path. This function only sets some variables which are used only in the 'transfer' function. The call chain is: .transfer --> exynos_dsi_host_transfer --> exynos_dsi_init --> exynos_dsi_enable_clock (use burst_clk_rate and esc_clk_rate) --> exynos_dsi_set_pll (use pll_clk_rate) While at it, also handle cases where 'component_add()' fails. This patch is similar to commit 70505c2ef94b ("drm/exynos: dsi: Remove bridge node reference in removal") which fixed the issue in the remove function. Signed-off-by: Christophe JAILLET Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index eb1486d2dd227..ee96a95fb6be5 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1759,10 +1759,6 @@ static int exynos_dsi_probe(struct platform_device *pdev) dsi->dev = dev; dsi->driver_data = of_device_get_match_data(dev); - ret = exynos_dsi_parse_dt(dsi); - if (ret) - return ret; - dsi->supplies[0].supply = "vddcore"; dsi->supplies[1].supply = "vddio"; ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dsi->supplies), @@ -1821,11 +1817,25 @@ static int exynos_dsi_probe(struct platform_device *pdev) return ret; } + ret = exynos_dsi_parse_dt(dsi); + if (ret) + return ret; + platform_set_drvdata(pdev, &dsi->encoder); pm_runtime_enable(dev); - return component_add(dev, &exynos_dsi_component_ops); + ret = component_add(dev, &exynos_dsi_component_ops); + if (ret) + goto err_disable_runtime; + + return 0; + +err_disable_runtime: + pm_runtime_disable(dev); + of_node_put(dsi->in_bridge_node); + + return ret; } static int exynos_dsi_remove(struct platform_device *pdev) From f84e1ba336a4f47ae251e4d2d8a694902571b0df Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Sun, 17 May 2020 20:36:55 +0100 Subject: [PATCH 8/8] drm/exynos-vidi: convert platform driver to use dev_groups Platform drivers now have the option to have the platform core create and remove any needed sysfs attribute files. So take advantage of that and do not register "by hand" a sysfs file. Cc: Inki Dae Cc: Joonyoung Shim Cc: Seung-Woo Kim Cc: Kyungmin Park Cc: dri-devel@lists.freedesktop.org Signed-off-by: Emil Velikov Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 26 ++++++++---------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 2824671216999..e5662bdcbbde3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -214,6 +214,12 @@ static ssize_t vidi_store_connection(struct device *dev, static DEVICE_ATTR(connection, 0644, vidi_show_connection, vidi_store_connection); +static struct attribute *vidi_attrs[] = { + &dev_attr_connection.attr, + NULL, +}; +ATTRIBUTE_GROUPS(vidi); + int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, struct drm_file *file_priv) { @@ -439,7 +445,6 @@ static int vidi_probe(struct platform_device *pdev) { struct vidi_context *ctx; struct device *dev = &pdev->dev; - int ret; ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -453,23 +458,7 @@ static int vidi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ctx); - ret = device_create_file(dev, &dev_attr_connection); - if (ret < 0) { - DRM_DEV_ERROR(dev, - "failed to create connection sysfs.\n"); - return ret; - } - - ret = component_add(dev, &vidi_component_ops); - if (ret) - goto err_remove_file; - - return ret; - -err_remove_file: - device_remove_file(dev, &dev_attr_connection); - - return ret; + return component_add(dev, &vidi_component_ops); } static int vidi_remove(struct platform_device *pdev) @@ -494,5 +483,6 @@ struct platform_driver vidi_driver = { .driver = { .name = "exynos-drm-vidi", .owner = THIS_MODULE, + .dev_groups = vidi_groups, }, };