Generic driver code gets forcewake explicitly by gen6_gt_force_wake_get(), which keeps force wake counts before accessing low level fw get. However the underlying gen8 register write function access low level accessors directly. This leads to nested fw get from hardware, causing forcewake ack clear errors and/or hangs. Fix this by checking the forcewake count in gen8 accessors. Also implement read accessors for gen8 to gain symmetry for shadowed register access. References: https://bugs.freedesktop.org/show_bug.cgi?id=74007 Signed-off-by: Mika Kuoppala <mika.kuoppala@xxxxxxxxx> Cc: Ben Widawsky <benjamin.widawsky@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_uncore.c | 74 +++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index c628414..089feaa 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -498,6 +498,45 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ REG_READ_FOOTER; \ } +static const u32 gen8_shadowed_regs[] = { + FORCEWAKE_MT, + GEN6_RPNSWREQ, + GEN6_RC_VIDEO_FREQ, + RING_TAIL(RENDER_RING_BASE), + RING_TAIL(GEN6_BSD_RING_BASE), + RING_TAIL(VEBOX_RING_BASE), + RING_TAIL(BLT_RING_BASE), + /* TODO: Other registers are not yet used */ +}; + +static bool is_gen8_shadowed(struct drm_i915_private *dev_priv, u32 reg) +{ + int i; + for (i = 0; i < ARRAY_SIZE(gen8_shadowed_regs); i++) + if (reg == gen8_shadowed_regs[i]) + return true; + + return false; +} + +#define __gen8_read(x) \ +static u##x \ +gen8_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ + bool __needs_put = reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg); \ + REG_READ_HEADER(x); \ + __needs_put &= dev_priv->uncore.forcewake_count == 0; \ + if (__needs_put) { \ + dev_priv->uncore.funcs.force_wake_get(dev_priv, \ + FORCEWAKE_ALL); \ + } \ + val = __raw_i915_read##x(dev_priv, reg); \ + if (__needs_put) { \ + dev_priv->uncore.funcs.force_wake_put(dev_priv, \ + FORCEWAKE_ALL); \ + } \ + REG_READ_FOOTER; \ +} + #define __vlv_read(x) \ static u##x \ vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ @@ -531,6 +570,10 @@ __vlv_read(8) __vlv_read(16) __vlv_read(32) __vlv_read(64) +__gen8_read(8) +__gen8_read(16) +__gen8_read(32) +__gen8_read(64) __gen6_read(8) __gen6_read(16) __gen6_read(32) @@ -545,6 +588,7 @@ __gen4_read(32) __gen4_read(64) #undef __vlv_read +#undef __gen8_read #undef __gen6_read #undef __gen5_read #undef __gen4_read @@ -610,32 +654,12 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) REG_WRITE_FOOTER; \ } -static const u32 gen8_shadowed_regs[] = { - FORCEWAKE_MT, - GEN6_RPNSWREQ, - GEN6_RC_VIDEO_FREQ, - RING_TAIL(RENDER_RING_BASE), - RING_TAIL(GEN6_BSD_RING_BASE), - RING_TAIL(VEBOX_RING_BASE), - RING_TAIL(BLT_RING_BASE), - /* TODO: Other registers are not yet used */ -}; - -static bool is_gen8_shadowed(struct drm_i915_private *dev_priv, u32 reg) -{ - int i; - for (i = 0; i < ARRAY_SIZE(gen8_shadowed_regs); i++) - if (reg == gen8_shadowed_regs[i]) - return true; - - return false; -} - #define __gen8_write(x) \ static void \ gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ bool __needs_put = reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg); \ REG_WRITE_HEADER; \ + __needs_put &= dev_priv->uncore.forcewake_count == 0; \ if (__needs_put) { \ dev_priv->uncore.funcs.force_wake_get(dev_priv, \ FORCEWAKE_ALL); \ @@ -734,10 +758,10 @@ void intel_uncore_init(struct drm_device *dev) dev_priv->uncore.funcs.mmio_writew = gen8_write16; dev_priv->uncore.funcs.mmio_writel = gen8_write32; dev_priv->uncore.funcs.mmio_writeq = gen8_write64; - dev_priv->uncore.funcs.mmio_readb = gen6_read8; - dev_priv->uncore.funcs.mmio_readw = gen6_read16; - dev_priv->uncore.funcs.mmio_readl = gen6_read32; - dev_priv->uncore.funcs.mmio_readq = gen6_read64; + dev_priv->uncore.funcs.mmio_readb = gen8_read8; + dev_priv->uncore.funcs.mmio_readw = gen8_read16; + dev_priv->uncore.funcs.mmio_readl = gen8_read32; + dev_priv->uncore.funcs.mmio_readq = gen8_read64; break; case 7: case 6: -- 1.7.9.5 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx