From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933483AbcIODNC (ORCPT ); Wed, 14 Sep 2016 23:13:02 -0400 Received: from m12-17.163.com ([220.181.12.17]:53225 "EHLO m12-17.163.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755877AbcIODNB (ORCPT ); Wed, 14 Sep 2016 23:13:01 -0400 From: bobcao3 To: Daniel Vetter , Jani Nikula , David Airlie Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Icenowy Zheng , stable@vger.kernel.org, bobcao3 Subject: [PATCH] DRM: i915: Fix gen8 graphics on Broadwell-U. These patches stop the random gpu hang on my XPS-13-9343, kernel version 4.8-rc5. Date: Thu, 15 Sep 2016 11:12:08 +0800 Message-Id: <20160915031208.20191-1-bobcaocheng@163.com> X-Mailer: git-send-email 2.10.0 X-CM-TRANSID: EcCowADX7QKUEdpXGnddBw--.932S3 X-Coremail-Antispam: 1Uf129KBjvJXoW3Gw45WF4ktr45Jw45Cw15Arb_yoW7tFy7pF 43Ja4jvrW0yr1xK3y7Za18Za43J3Zaq34rur97K3s7uF43CFnYgr4jvFy5GryUCF97Wrnx Zr9rX3WIvF9Fyr7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07UPPEfUUUUU= X-Originating-IP: [180.159.85.228] X-CM-SenderInfo: 5ereutprfkv0rj6rljoofrz/1tbiFBblK1aDpHujngAAs7 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Signed-off-by: bobcao3 --- drivers/gpu/drm/i915/i915_gem_gtt.c | 6 ++++ drivers/gpu/drm/i915/i915_gem_stolen.c | 61 ++++++++++++++++----------------- drivers/gpu/drm/i915/i915_reg.h | 6 ++++ drivers/gpu/drm/i915/intel_ringbuffer.c | 19 +++++++++- 4 files changed, 59 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 7a30af7..0b05dd9 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2907,6 +2907,12 @@ static unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl) if (bdw_gmch_ctl > 4) bdw_gmch_ctl = 4; #endif +#ifdef CONFIG_X86_64 + /* Limit 64b platforms to a 4GB GGTT */ + /* DMA 4GB protection */ + if (bdw_gmch_ctl > 8) + bdw_gmch_ctl = 8; +#endif return bdw_gmch_ctl << 20; } diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 66be299a1..da272ae 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -352,47 +352,44 @@ static void gen8_get_stolen_reserved(struct drm_i915_private *dev_priv, unsigned long *base, unsigned long *size) { uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); + unsigned long stolen_top; + struct i915_ggtt *ggtt = &dev_priv->ggtt; *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; switch (reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK) { case GEN8_STOLEN_RESERVED_1M: - *size = 1024 * 1024; + *size = 1 << 10 << 10; break; case GEN8_STOLEN_RESERVED_2M: - *size = 2 * 1024 * 1024; + *size = 2 << 10 << 10; break; case GEN8_STOLEN_RESERVED_4M: - *size = 4 * 1024 * 1024; + *size = 4 << 10 << 10; break; case GEN8_STOLEN_RESERVED_8M: - *size = 8 * 1024 * 1024; + *size = 8 << 10 << 10; break; default: - *size = 8 * 1024 * 1024; - MISSING_CASE(reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK); - } -} - -static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv, - unsigned long *base, unsigned long *size) -{ - struct i915_ggtt *ggtt = &dev_priv->ggtt; - uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED); - unsigned long stolen_top; + /* Whatever if it is a BDW device or SKL device + * Or others devices.. + * This way is always going to work on 5th + * generation Intel Processer + */ + stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size; - stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size; + *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; - *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK; + /* MLIMIT - MBASE => PEG */ + /* -- mobile-5th-gen-core-family-datasheet-vol-2.pdf */ + if (*base == 0) { + *size = 0; + MISSING_CASE(reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK); + } else + *size = stolen_top - *base; - /* On these platforms, the register doesn't have a size field, so the - * size is the distance between the base and the top of the stolen - * memory. We also have the genuine case where base is zero and there's - * nothing reserved. */ - if (*base == 0) - *size = 0; - else - *size = stolen_top - *base; + break; + } } int i915_gem_init_stolen(struct drm_device *dev) @@ -442,14 +439,14 @@ int i915_gem_init_stolen(struct drm_device *dev) gen7_get_stolen_reserved(dev_priv, &reserved_base, &reserved_size); break; + case 8: + gen8_get_stolen_reserved(dev_priv, &reserved_base, + &reserved_size); + break; default: - if (IS_BROADWELL(dev_priv) || - IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev)) - bdw_get_stolen_reserved(dev_priv, &reserved_base, - &reserved_size); - else - gen8_get_stolen_reserved(dev_priv, &reserved_base, - &reserved_size); + // FIXME: This seemed like going to work + gen8_get_stolen_reserved(dev_priv, &reserved_base, + &reserved_size); break; } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index bf2cad3..3dce37b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1748,6 +1748,12 @@ enum skl_disp_power_wells { #define RING_INDIRECT_CTX_OFFSET(base) _MMIO((base)+0x1c8) /* gen8+ */ #define RING_CTX_TIMESTAMP(base) _MMIO((base)+0x3a8) /* gen8+ */ +// 64 bit, low 32 preserved +#define IOTLB_INVALID(base) _MMIO((base)+0x508 + 4) /* gen8+ */ +#define IOTLB_INVALID_IVT (1<<31) +#define IOTLB_GLOBAL_INV_REQ (1<<28) +#define IOTLB_INVALID_IAIG (1<<25) + #define ERROR_GEN6 _MMIO(0x40a0) #define GEN7_ERR_INT _MMIO(0x44040) #define ERR_INT_POISON (1<<31) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 1d3161b..77bb6ff 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -498,7 +498,24 @@ static void intel_ring_setup_status_page(struct intel_engine_cs *engine) * arises: do we still need this and if so how should we go about * invalidating the TLB? */ - if (IS_GEN(dev_priv, 6, 7)) { + /* Respond to this question: + * According to mobile-5th-gen-core-family-datasheet-vol-2 from Intel + * There are registers for invalidation, set those registers will + * cause the hardware to perform IOTLB invalidation. + */ + if (IS_GEN8(dev_priv)) { + i915_reg_t reg = IOTLB_INVALID(engine->mmio_base); + + /* ring should be idle before issuing a sync flush*/ + WARN_ON((I915_READ_MODE(engine) & MODE_IDLE) == 0); + + I915_WRITE(reg, 0x0 | IOTLB_INVALID_IVT | IOTLB_GLOBAL_INV_REQ); + + if (intel_wait_for_register(dev_priv, + reg, IOTLB_INVALID_IAIG, 0, + 1000)) + DRM_ERROR("%s: wait for TLB invalidation timed out\n", + engine->name); + } else if (IS_GEN(dev_priv, 6, 7)) { i915_reg_t reg = RING_INSTPM(engine->mmio_base); /* ring should be idle before issuing a sync flush*/ -- 2.10.0