From patchwork Thu Apr 2 15:29:47 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas Stach X-Patchwork-Id: 6149561 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 446859F1BE for ; Thu, 2 Apr 2015 15:31:52 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5F528203AC for ; Thu, 2 Apr 2015 15:31:51 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 32878203AB for ; Thu, 2 Apr 2015 15:31:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B847B6EAB6; Thu, 2 Apr 2015 08:31:04 -0700 (PDT) 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 [92.198.50.35]) by gabe.freedesktop.org (Postfix) with ESMTP id 919B86EA4B for ; Thu, 2 Apr 2015 08:30:58 -0700 (PDT) Received: from dude.hi.4.pengutronix.de ([10.1.0.7] helo=dude.pengutronix.de.) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1Ydh57-0005OD-Sn; Thu, 02 Apr 2015 17:30:57 +0200 From: Lucas Stach To: dri-devel@lists.freedesktop.org Subject: [PATCH RFC 045/111] staging: etnaviv: add support to insert a MMU flush into GPU stream Date: Thu, 2 Apr 2015 17:29:47 +0200 Message-Id: <1427988653-754-46-git-send-email-l.stach@pengutronix.de> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1427988653-754-1-git-send-email-l.stach@pengutronix.de> References: <1427988653-754-1-git-send-email-l.stach@pengutronix.de> X-SA-Exim-Connect-IP: 10.1.0.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: Russell King , kernel@pengutronix.de 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-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Russell King Add a flag to indicate that the GPU MMU needs to be flushed before executing the next set of command buffers. This is necessary to ensure that the GPU sees updated page table entries which may have been modified by GEM. It is expected that userspace will have flushed the caches at the end of the previous command buffers, so there will be no cache writebacks pending. Signed-off-by: Russell King --- drivers/staging/etnaviv/etnaviv_buffer.c | 64 +++++++++++++++++++++++++------- drivers/staging/etnaviv/etnaviv_mmu.h | 1 + 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/drivers/staging/etnaviv/etnaviv_buffer.c b/drivers/staging/etnaviv/etnaviv_buffer.c index 026489baeda7..96661e513d7d 100644 --- a/drivers/staging/etnaviv/etnaviv_buffer.c +++ b/drivers/staging/etnaviv/etnaviv_buffer.c @@ -17,6 +17,7 @@ #include "etnaviv_gpu.h" #include "etnaviv_gem.h" +#include "etnaviv_mmu.h" #include "common.xml.h" #include "state.xml.h" @@ -162,34 +163,38 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event, struct etnaviv_gem_object *buffer = to_etnaviv_bo(gpu->buffer); struct etnaviv_gem_object *cmd; u32 *lw = buffer->vaddr + ((buffer->offset - 4) * 4); - u32 back, link_target, link_size; + u32 back, link_target, link_size, reserve_size; u32 i; if (drm_debug & DRM_UT_DRIVER) etnaviv_buffer_dump(gpu, buffer, 0, 0x50); + reserve_size = 6; + + /* + * If we need to flush the MMU prior to submitting this buffer, we + * will need to append a mmu flush load state, followed by a new + * link to this buffer - a total of four additional words. + */ + if (gpu->mmu->need_flush) + reserve_size += 4; + /* * if we are going to completely overflow the buffer, we need to wrap. */ - if (buffer->offset + 6 > buffer->base.size / sizeof(uint32_t)) + if (buffer->offset + reserve_size > + buffer->base.size / sizeof(uint32_t)) buffer->offset = 0; /* save offset back into main buffer */ - back = buffer->offset; + back = buffer->offset + reserve_size - 6; link_target = buffer->paddr + buffer->offset * 4; link_size = 6; - /* Save the event and buffer position of the new event trigger */ - gpu->event[event].fence = submit->fence; - gpu->event[event].ring_pos = buffer->offset; - - /* trigger event */ - CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) | - VIVS_GL_EVENT_FROM_PE); - - /* append WAIT/LINK to main buffer */ - CMD_WAIT(buffer); - CMD_LINK(buffer, 2, buffer->paddr + ((buffer->offset - 1) * 4)); + if (gpu->mmu->need_flush) { + /* Skip over the MMU flush and LINK instructions */ + link_target += 4 * sizeof(uint32_t); + } /* update offset for every cmd stream */ for (i = submit->nr_cmds; i--; ) { @@ -228,6 +233,37 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event, pr_info("event: %d\n", event); } + if (gpu->mmu->need_flush) { + uint32_t new_target = buffer->paddr + buffer->offset * + sizeof(uint32_t); + + /* Add the MMU flush */ + CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_MMU, + VIVS_GL_FLUSH_MMU_FLUSH_FEMMU | + VIVS_GL_FLUSH_MMU_FLUSH_PEMMU); + + /* And the link to the first buffer */ + CMD_LINK(buffer, link_size, link_target); + + /* Update the link target to point to the flush */ + link_target = new_target; + link_size = 4; + + gpu->mmu->need_flush = false; + } + + /* Save the event and buffer position of the new event trigger */ + gpu->event[event].fence = submit->fence; + gpu->event[event].ring_pos = buffer->offset; + + /* trigger event */ + CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) | + VIVS_GL_EVENT_FROM_PE); + + /* append WAIT/LINK to main buffer */ + CMD_WAIT(buffer); + CMD_LINK(buffer, 2, buffer->paddr + ((buffer->offset - 1) * 4)); + /* Change WAIT into a LINK command; write the address first. */ *(lw + 1) = link_target; mb(); diff --git a/drivers/staging/etnaviv/etnaviv_mmu.h b/drivers/staging/etnaviv/etnaviv_mmu.h index 7b97ef35d290..b3a0e3c98372 100644 --- a/drivers/staging/etnaviv/etnaviv_mmu.h +++ b/drivers/staging/etnaviv/etnaviv_mmu.h @@ -23,6 +23,7 @@ struct etnaviv_iommu { struct drm_device *dev; struct iommu_domain *domain; + bool need_flush; }; int etnaviv_iommu_attach(struct etnaviv_iommu *iommu, const char **names,