From patchwork Mon Aug 22 11:01:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas Stach X-Patchwork-Id: 9293397 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 604DC60574 for ; Mon, 22 Aug 2016 11:01:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 545B0287D2 for ; Mon, 22 Aug 2016 11:01:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 49307287E5; Mon, 22 Aug 2016 11:01:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EA801287D2 for ; Mon, 22 Aug 2016 11:01:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3C4DE6E429; Mon, 22 Aug 2016 11:01:16 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by gabe.freedesktop.org (Postfix) with ESMTPS id 20D866E428 for ; Mon, 22 Aug 2016 11:01:15 +0000 (UTC) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7] helo=dude.pengutronix.de.) by metis.ext.pengutronix.de with esmtp (Exim 4.80) (envelope-from ) id 1bbmyf-00071Z-Kt; Mon, 22 Aug 2016 13:01:13 +0200 From: Lucas Stach To: dri-devel@lists.freedesktop.org Subject: [PATCH 13/18] drm/etnaviv: map cmdbuf through MMU on version 2 Date: Mon, 22 Aug 2016 13:01:07 +0200 Message-Id: <1471863672-7104-14-git-send-email-l.stach@pengutronix.de> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1471863672-7104-1-git-send-email-l.stach@pengutronix.de> References: <1471863672-7104-1-git-send-email-l.stach@pengutronix.de> X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: l.stach@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: dri-devel@lists.freedesktop.org Cc: kernel@pengutronix.de, Russell King X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP With MMUv2 all buffers need to be mapped through the MMU once it is enabled. Align the buffer size to 4K, as the MMU is only able to map page aligned buffers. Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 4 ++++ drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 2 ++ drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 42 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/etnaviv/etnaviv_mmu.h | 2 ++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index fe541a3cdc10..4c706438c7c8 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1151,6 +1151,9 @@ struct etnaviv_cmdbuf *etnaviv_gpu_cmdbuf_new(struct etnaviv_gpu *gpu, u32 size, if (!cmdbuf) return NULL; + if (gpu->mmu->version == ETNAVIV_IOMMU_V2) + size = ALIGN(size, SZ_4K); + cmdbuf->vaddr = dma_alloc_wc(gpu->dev, size, &cmdbuf->paddr, GFP_KERNEL); if (!cmdbuf->vaddr) { @@ -1166,6 +1169,7 @@ struct etnaviv_cmdbuf *etnaviv_gpu_cmdbuf_new(struct etnaviv_gpu *gpu, u32 size, void etnaviv_gpu_cmdbuf_free(struct etnaviv_cmdbuf *cmdbuf) { + etnaviv_iommu_put_cmdbuf_va(cmdbuf->gpu, cmdbuf); dma_free_wc(cmdbuf->gpu->dev, cmdbuf->size, cmdbuf->vaddr, cmdbuf->paddr); kfree(cmdbuf); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h index 7a10a9c32a70..73c278dc3706 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -160,6 +160,8 @@ struct etnaviv_cmdbuf { dma_addr_t paddr; u32 size; u32 user_size; + /* vram node used if the cmdbuf is mapped through the MMUv2 */ + struct drm_mm_node vram_node; /* fence after which this buffer is to be disposed */ struct fence *fence; /* target exec state */ diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c index 69ea0a0a70c2..98c84ef862c7 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -319,9 +319,49 @@ void etnaviv_iommu_restore(struct etnaviv_gpu *gpu) u32 etnaviv_iommu_get_cmdbuf_va(struct etnaviv_gpu *gpu, struct etnaviv_cmdbuf *buf) { - return buf->paddr - gpu->memory_base; + struct etnaviv_iommu *mmu = gpu->mmu; + + if (mmu->version == ETNAVIV_IOMMU_V1) { + return buf->paddr - gpu->memory_base; + } else { + int ret; + + if (buf->vram_node.allocated) + return (u32)buf->vram_node.start; + + mutex_lock(&mmu->lock); + ret = etnaviv_iommu_find_iova(mmu, &buf->vram_node, buf->size); + if (ret < 0) { + mutex_unlock(&mmu->lock); + return 0; + } + ret = iommu_map(mmu->domain, buf->vram_node.start, buf->paddr, + buf->size, IOMMU_READ); + if (ret < 0) { + drm_mm_remove_node(&buf->vram_node); + mutex_unlock(&mmu->lock); + return 0; + } + mmu->last_iova = buf->vram_node.start + buf->size; + gpu->mmu->need_flush = true; + mutex_unlock(&mmu->lock); + + return (u32)buf->vram_node.start; + } } +void etnaviv_iommu_put_cmdbuf_va(struct etnaviv_gpu *gpu, + struct etnaviv_cmdbuf *buf) +{ + struct etnaviv_iommu *mmu = gpu->mmu; + + if (mmu->version == ETNAVIV_IOMMU_V2 && buf->vram_node.allocated) { + mutex_lock(&mmu->lock); + iommu_unmap(mmu->domain, buf->vram_node.start, buf->size); + drm_mm_remove_node(&buf->vram_node); + mutex_unlock(&mmu->lock); + } +} size_t etnaviv_iommu_dump_size(struct etnaviv_iommu *iommu) { struct etnaviv_iommu_ops *ops; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h index 0d34325a318a..e787e49c9693 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h @@ -64,6 +64,8 @@ void etnaviv_iommu_destroy(struct etnaviv_iommu *iommu); u32 etnaviv_iommu_get_cmdbuf_va(struct etnaviv_gpu *gpu, struct etnaviv_cmdbuf *buf); +void etnaviv_iommu_put_cmdbuf_va(struct etnaviv_gpu *gpu, + struct etnaviv_cmdbuf *buf); size_t etnaviv_iommu_dump_size(struct etnaviv_iommu *iommu); void etnaviv_iommu_dump(struct etnaviv_iommu *iommu, void *buf);