From patchwork Wed Feb 13 09:25:58 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 2134641 Return-Path: X-Original-To: patchwork-intel-gfx@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 C02ACDFE75 for ; Wed, 13 Feb 2013 09:26:31 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BAEB9E65C0 for ; Wed, 13 Feb 2013 01:26:31 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (smtp.fireflyinternet.com [109.228.6.236]) by gabe.freedesktop.org (Postfix) with ESMTP id DBDDDE5D50 for ; Wed, 13 Feb 2013 01:26:22 -0800 (PST) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.73.22; Received: from arrandale.alporthouse.com (unverified [78.156.73.22]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP id 128982646-1500050 for multiple; Wed, 13 Feb 2013 09:26:00 +0000 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Wed, 13 Feb 2013 09:25:58 +0000 Message-Id: <1360747558-16493-1-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 1.7.10.4 X-Originating-IP: 78.156.73.22 Cc: ncm@cantrip.org, stable@vger.kernel.org Subject: [Intel-gfx] [PATCH] drm/i915: Disable WC PTE updates to w/a buggy IOMMU on ILK X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Whilst IOMMU is enabled for the Intel GPU on Ironlake, it appears that using WC writes to update the PTE on the GPU fail miserably. The result looks like the majority of the writes do not land leading to lots of screen corruption and a hard system hang. Reported-by: Nathan Myers Bugzilla: https://bugzilla.freedesktop.org/show_bug.cgi?id=60391 Signed-off-by: Chris Wilson Cc: stable@vger.kernel.org --- drivers/char/agp/intel-gtt.c | 58 +++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index dbd901e..ae953f4 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -562,6 +562,41 @@ static void intel_gtt_cleanup(void) intel_gtt_teardown_scratch_page(); } +/* Certain Gen5 chipsets require require idling the GPU before + * unmapping anything from the GTT when VT-d is enabled. + */ +static inline int needs_ilk_vtd_wa(void) +{ +#ifdef CONFIG_INTEL_IOMMU + const unsigned short gpu_devid = intel_private.pcidev->device; + + /* Query intel_iommu to see if we need the workaround. Presumably that + * was loaded first. + */ + if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || + gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) && + intel_iommu_gfx_mapped) + return 1; +#endif + return 0; +} + + +static bool intel_gtt_can_wc(void) +{ + if (INTEL_GTT_GEN <= 2) + return false; + + if (INTEL_GTT_GEN > 6) + return false; + + /* Reports of major corruption with ILK vt'd enabled */ + if (needs_ilk_vtd_wa()) + return false; + + return true; +} + static int intel_gtt_init(void) { u32 gma_addr; @@ -591,7 +626,7 @@ static int intel_gtt_init(void) gtt_map_size = intel_private.base.gtt_total_entries * 4; intel_private.gtt = NULL; - if (INTEL_GTT_GEN < 6 && INTEL_GTT_GEN > 2) + if (intel_gtt_can_wc()) intel_private.gtt = ioremap_wc(intel_private.gtt_bus_addr, gtt_map_size); if (intel_private.gtt == NULL) @@ -1070,25 +1105,6 @@ static void i965_write_entry(dma_addr_t addr, writel(addr | pte_flags, intel_private.gtt + entry); } -/* Certain Gen5 chipsets require require idling the GPU before - * unmapping anything from the GTT when VT-d is enabled. - */ -static inline int needs_idle_maps(void) -{ -#ifdef CONFIG_INTEL_IOMMU - const unsigned short gpu_devid = intel_private.pcidev->device; - - /* Query intel_iommu to see if we need the workaround. Presumably that - * was loaded first. - */ - if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || - gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) && - intel_iommu_gfx_mapped) - return 1; -#endif - return 0; -} - static int i9xx_setup(void) { u32 reg_addr, gtt_addr; @@ -1116,7 +1132,7 @@ static int i9xx_setup(void) break; } - if (needs_idle_maps()) + if (needs_ilk_vtd_wa()) intel_private.base.do_idle_maps = 1; intel_i9xx_setup_flush();