From patchwork Mon Dec 10 06:35:00 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Inki Dae X-Patchwork-Id: 1855591 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 1229BDFB79 for ; Mon, 10 Dec 2012 07:41:26 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CD231E6045 for ; Sun, 9 Dec 2012 23:41:25 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) by gabe.freedesktop.org (Postfix) with ESMTP id 574EAE5EC3 for ; Sun, 9 Dec 2012 22:35:03 -0800 (PST) Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MES0041JY9JYU70@mailout2.samsung.com> for dri-devel@lists.freedesktop.org; Mon, 10 Dec 2012 15:35:01 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [203.254.230.44]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 8B.F5.01231.59285C05; Mon, 10 Dec 2012 15:35:01 +0900 (KST) X-AuditID: cbfee61a-b7fa66d0000004cf-ea-50c58295efbe Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id BA.F5.01231.59285C05; Mon, 10 Dec 2012 15:35:01 +0900 (KST) Received: from daeinki-desktop.10.32.193.11 ([10.90.51.53]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MES00CP8YADT940@mmp2.samsung.com> for dri-devel@lists.freedesktop.org; Mon, 10 Dec 2012 15:35:01 +0900 (KST) From: Inki Dae To: airlied@linux.ie, dri-devel@lists.freedesktop.org Subject: [PATCH v3] drm/exynos: use DMA_ATTR_NO_KERNEL_MAPPING attribute Date: Mon, 10 Dec 2012 15:35:00 +0900 Message-id: <1355121300-16531-1-git-send-email-inki.dae@samsung.com> X-Mailer: git-send-email 1.7.4.1 In-reply-to: <1355104554-4287-1-git-send-email-inki.dae@samsung.com> References: <1355104554-4287-1-git-send-email-inki.dae@samsung.com> DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrNLMWRmVeSWpSXmKPExsVy+t8zHd2pTUcDDFbtM7O48vU9mwOjx/3u 40wBjFFcNimpOZllqUX6dglcGfdvfWMuWGReMXvDfPYGxgl6XYycHBICJhLfv85mhLDFJC7c W88GYgsJLGOU2L1PCaZm28/pQHEuoPh0RomXi19COeuZJGac/QPWzSagKjFxxX2wbhEBU4mO SUtZQGxmgUKJhT1PwWxhAQ+Js80rwepZgOqX3N7H3sXIwcEr4CJxdWIlxDIFiQX33oKN4QQK 710/ixniIGeJbZfus0O0Ckh8m3yIBaRVQkBWYtMBZpBzJAQus0m0bDjEAjFHUuLgihssExiF FzAyrGIUTS1ILihOSs811CtOzC0uzUvXS87P3cQICUGpHYwrGywOMQpwMCrx8AYoHg0QYk0s K67MPcQowcGsJMLLdexIgBBvSmJlVWpRfnxRaU5q8SFGH6BLJjJLiSbnA+MjryTe0NjA2NDQ 0tDM1NLUAIewkjhvs0dKgJBAemJJanZqakFqEcw4Jg5OqQbGFc+/ci7lzo55ceG45ZHOt3Oe fNCp7GJezn5k3lcmvtfcj/j1NPLDty35c/Flj+KDZRK6M/krhL/1PD9fpDOhWDOne/rO0wdf quu3Pdh2PaY36OH7qqzNATN/+te3FbmcSeb6UrpJL9JktZcF36eqF5suSFZ0BWusCl33wtej /5mp+OGdctMjlViKMxINtZiLihMBAC/gdG4CAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupmkeLIzCtJLcpLzFFi42I5/e+xoO7UpqMBBv2bDCyufH3P5sDocb/7 OFMAY1QDo01GamJKapFCal5yfkpmXrqtkndwvHO8qZmBoa6hpYW5kkJeYm6qrZKLT4CuW2YO 0FglhbLEnFKgUEBicbGSvh2mCaEhbroWMI0Rur4hQXA9RgZoIGEdY8b9W9+YCxaZV8zeMJ+9 gXGCXhcjJ4eEgInEtp/T2SBsMYkL99YD2VwcQgLTGSVeLn4J5axnkphx9g8jSBWbgKrExBX3 wTpEBEwlOiYtZQGxmQUKJRb2PAWzhQU8JM42rwSrZwGqX3J7H3sXIwcHr4CLxNWJlRDLFCQW 3HsLNoYTKLx3/SxmEFtIwFli26X77BMYeRcwMqxiFE0tSC4oTkrPNdQrTswtLs1L10vOz93E CA7xZ1I7GFc2WBxiFOBgVOLhDVA8GiDEmlhWXJl7iFGCg1lJhJfr2JEAId6UxMqq1KL8+KLS nNTiQ4w+QEdNZJYSTc4Hxl9eSbyhsYmZkaWRmbGJubExDmElcd5mj5QAIYH0xJLU7NTUgtQi mHFMHJxSDYzzyre2u/4PO/qg3ag5Qcr/96y8iW5mfBN32l07J3Z9m9yKQEOL15M/TtfZPul8 9p2Sv/klO0OXaf0tDbpZdVJ0sV9cE5+XalWmmPjM/mMX44/aFPQf4blTdqy3NuHYy+/G+8QM trQtudZsGtsxT+1lp1t33dkTd7htw5OjDaNeTmqY1BR77qUSS3FGoqEWc1FxIgDx1uuNngIA AA== X-CFilter-Loop: Reflected Cc: kyungmin.park@samsung.com, sw0312.kim@samsung.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Changelog v3: just code cleanup. Changelog v2: fix argument to dma_mmap_attr function. - use pages instead of kvaddr because kvaddr is 0 with DMA_ATTR_NO_KERNEL_MAPPING. Changelog v1: When gem allocation is requested, kernel space mapping isn't needed. But if need, such as console framebuffer, the physical pages would be mapped with kernel space though vmap function. Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_buf.c | 31 ++++++++++------------------ drivers/gpu/drm/exynos/exynos_drm_fb.c | 4 +-- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 18 +++++++++++++++- drivers/gpu/drm/exynos/exynos_drm_gem.c | 2 +- drivers/gpu/drm/exynos/exynos_drm_gem.h | 2 + 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c index 72bf97b..9732043 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c @@ -35,6 +35,7 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, { int ret = 0; enum dma_attr attr = DMA_ATTR_FORCE_CONTIGUOUS; + unsigned int nr_pages; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -49,40 +50,31 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, attr = DMA_ATTR_WRITE_COMBINE; dma_set_attr(attr, &buf->dma_attrs); + dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &buf->dma_attrs); - buf->kvaddr = dma_alloc_attrs(dev->dev, buf->size, + buf->pages = dma_alloc_attrs(dev->dev, buf->size, &buf->dma_addr, GFP_KERNEL, &buf->dma_attrs); - if (!buf->kvaddr) { + if (!buf->pages) { DRM_ERROR("failed to allocate buffer.\n"); return -ENOMEM; } - buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + nr_pages = buf->size >> PAGE_SHIFT; + buf->sgt = drm_prime_pages_to_sg(buf->pages, nr_pages); if (!buf->sgt) { - DRM_ERROR("failed to allocate sg table.\n"); + DRM_ERROR("failed to get sg table.\n"); ret = -ENOMEM; goto err_free_attrs; } - ret = dma_get_sgtable(dev->dev, buf->sgt, buf->kvaddr, buf->dma_addr, - buf->size); - if (ret < 0) { - DRM_ERROR("failed to get sgtable.\n"); - goto err_free_sgt; - } - - DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", - (unsigned long)buf->kvaddr, + DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n", (unsigned long)buf->dma_addr, buf->size); return ret; -err_free_sgt: - kfree(buf->sgt); - buf->sgt = NULL; err_free_attrs: - dma_free_attrs(dev->dev, buf->size, buf->kvaddr, + dma_free_attrs(dev->dev, buf->size, buf->pages, (dma_addr_t)buf->dma_addr, &buf->dma_attrs); buf->dma_addr = (dma_addr_t)NULL; @@ -99,8 +91,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, return; } - DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", - (unsigned long)buf->kvaddr, + DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n", (unsigned long)buf->dma_addr, buf->size); @@ -109,7 +100,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, kfree(buf->sgt); buf->sgt = NULL; - dma_free_attrs(dev->dev, buf->size, buf->kvaddr, + dma_free_attrs(dev->dev, buf->size, buf->pages, (dma_addr_t)buf->dma_addr, &buf->dma_attrs); buf->dma_addr = (dma_addr_t)NULL; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 7413f4b..764571c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -297,9 +297,7 @@ struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb, if (!buffer) return NULL; - DRM_DEBUG_KMS("vaddr = 0x%lx, dma_addr = 0x%lx\n", - (unsigned long)buffer->kvaddr, - (unsigned long)buffer->dma_addr); + DRM_DEBUG_KMS("dma_addr = 0x%lx\n", (unsigned long)buffer->dma_addr); return buffer; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 885ef23..f433eb7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -65,7 +65,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info, if (vm_size > buffer->size) return -EINVAL; - ret = dma_mmap_attrs(helper->dev->dev, vma, buffer->kvaddr, + ret = dma_mmap_attrs(helper->dev->dev, vma, buffer->pages, buffer->dma_addr, buffer->size, &buffer->dma_attrs); if (ret < 0) { DRM_ERROR("failed to mmap.\n"); @@ -109,6 +109,17 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, return -EFAULT; } + /* map pages with kernel virtual space. */ + if (!buffer->kvaddr) { + unsigned int nr_pages = buffer->size >> PAGE_SHIFT; + buffer->kvaddr = vmap(buffer->pages, nr_pages, VM_MAP, + pgprot_writecombine(PAGE_KERNEL)); + if (!buffer->kvaddr) { + DRM_ERROR("failed to map pages to kernel space.\n"); + return -EIO; + } + } + /* buffer count to framebuffer always is 1 at booting time. */ exynos_drm_fb_set_buf_cnt(fb, 1); @@ -305,8 +316,13 @@ err_init: 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_obj *exynos_gem_obj = exynos_fbd->exynos_gem_obj; struct drm_framebuffer *fb; + if (exynos_gem_obj->buffer->kvaddr) + vunmap(exynos_gem_obj->buffer->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 9922724..d48183e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -400,7 +400,7 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, if (vm_size > buffer->size) return -EINVAL; - ret = dma_mmap_attrs(drm_dev->dev, vma, buffer->kvaddr, + ret = dma_mmap_attrs(drm_dev->dev, vma, buffer->pages, buffer->dma_addr, buffer->size, &buffer->dma_attrs); if (ret < 0) { diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index d3ea106..f11f2af 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -40,6 +40,7 @@ * - this address could be physical address without IOMMU and * device address with IOMMU. * @write: whether pages will be written to by the caller. + * @pages: Array of backing pages. * @sgt: sg table to transfer page data. * @size: size of allocated memory region. * @pfnmap: indicate whether memory region from userptr is mmaped with @@ -51,6 +52,7 @@ struct exynos_drm_gem_buf { dma_addr_t dma_addr; struct dma_attrs dma_attrs; unsigned int write; + struct page **pages; struct sg_table *sgt; unsigned long size; bool pfnmap;