diff options
author | Dave Airlie <airlied@redhat.com> | 2016-07-15 13:50:58 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-07-15 13:50:58 +1000 |
commit | ff37c05a996bb96eccc21f4fb1b32ba0e24f3443 (patch) | |
tree | c09b09b37521f2f8f3f7a9bb3b0a33a2b3bde1a1 /drivers/gpu/drm/i915/intel_uncore.c | |
parent | 6c181c82106e12dced317e93a7a396cbb8c64f75 (diff) | |
parent | 0b2c0582f1570bfc95aa9ac1cd340a215d8e8335 (diff) |
Merge tag 'drm-intel-next-2016-07-11' of git://anongit.freedesktop.org/drm-intel into drm-next
- select igt testing depencies for CONFIG_DRM_I915_DEBUG (Chris)
- track outputs in crtc state and clean up all our ad-hoc connector/encoder
walking in modest code (Ville)
- demidlayer drm_device/drm_i915_private (Chris Wilson)
- thundering herd fix from Chris Wilson, with lots of help from Tvrtko Ursulin
- piles of assorted clean and fallout from the thundering herd fix
- documentation and more tuning for waitboosting (Chris)
- pooled EU support on bxt (Arun Siluvery)
- bxt support is no longer considered prelimary!
- ring/engine vfunc cleanup from Tvrtko
- introduce intel_wait_for_register helper (Chris)
- opregion updates (Jani Nukla)
- tuning and fixes for wait_for macros (Tvrkto&Imre)
- more kabylake pci ids (Rodrigo)
- pps cleanup and fixes for bxt (Imre)
- move sink crc support over to atomic state (Maarten)
- fix up async fbdev init ordering (Chris)
- fbc fixes from Paulo and Chris
* tag 'drm-intel-next-2016-07-11' of git://anongit.freedesktop.org/drm-intel: (223 commits)
drm/i915: Update DRIVER_DATE to 20160711
drm/i915: Select DRM_VGEM for igt
drm/i915: Select X86_MSR for igt
drm/i915: Fill unused GGTT with scratch pages for VT-d
drm/i915: Introduce Kabypoint PCH for Kabylake H/DT.
drm/i915:gen9: implement WaMediaPoolStateCmdInWABB
drm/i915: Check for invalid cloning earlier during modeset
drm/i915: Simplify hdmi_12bpc_possible()
drm/i915: Kill has_dsi_encoder
drm/i915: s/INTEL_OUTPUT_DISPLAYPORT/INTEL_OUTPUT_DP/
drm/i915: Replace some open coded intel_crtc_has_dp_encoder()s
drm/i915: Kill has_dp_encoder from pipe_config
drm/i915: Replace manual lvds and sdvo/hdmi counting with intel_crtc_has_type()
drm/i915: Unify intel_pipe_has_type() and intel_pipe_will_have_type()
drm/i915: Add output_types bitmask into the crtc state
drm/i915: Remove encoder type checks from MST suspend/resume
drm/i915: Don't mark eDP encoders as MST capable
drm/i915: avoid wait_for_atomic() in non-atomic host2guc_action()
drm/i915: Group the irq breadcrumb variables into the same cacheline
drm/i915: Wake up the bottom-half if we steal their interrupt
...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_uncore.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_uncore.c | 113 |
1 files changed, 87 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index c1ca458d688e..ff80a81b1a84 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1299,9 +1299,11 @@ static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv) fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER, FORCEWAKE_MT, FORCEWAKE_MT_ACK); + spin_lock_irq(&dev_priv->uncore.lock); fw_domains_get_with_thread_status(dev_priv, FORCEWAKE_ALL); ecobus = __raw_i915_read32(dev_priv, ECOBUS); fw_domains_put_with_fifo(dev_priv, FORCEWAKE_ALL); + spin_unlock_irq(&dev_priv->uncore.lock); if (!(ecobus & FORCEWAKE_MT_ENABLE)) { DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n"); @@ -1407,7 +1409,7 @@ static const struct register_whitelist { int i915_reg_read_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_reg_read *reg = data; struct register_whitelist const *entry = whitelist; unsigned size; @@ -1469,7 +1471,7 @@ static int i915_reset_complete(struct pci_dev *pdev) static int i915_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) { - struct pci_dev *pdev = dev_priv->dev->pdev; + struct pci_dev *pdev = dev_priv->drm.pdev; /* assert reset for at least 20 usec */ pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE); @@ -1488,14 +1490,14 @@ static int g4x_reset_complete(struct pci_dev *pdev) static int g33_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) { - struct pci_dev *pdev = dev_priv->dev->pdev; + struct pci_dev *pdev = dev_priv->drm.pdev; pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE); return wait_for(g4x_reset_complete(pdev), 500); } static int g4x_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) { - struct pci_dev *pdev = dev_priv->dev->pdev; + struct pci_dev *pdev = dev_priv->drm.pdev; int ret; pci_write_config_byte(pdev, I915_GDRST, @@ -1530,15 +1532,17 @@ static int ironlake_do_reset(struct drm_i915_private *dev_priv, I915_WRITE(ILK_GDSR, ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE); - ret = wait_for((I915_READ(ILK_GDSR) & - ILK_GRDOM_RESET_ENABLE) == 0, 500); + ret = intel_wait_for_register(dev_priv, + ILK_GDSR, ILK_GRDOM_RESET_ENABLE, 0, + 500); if (ret) return ret; I915_WRITE(ILK_GDSR, ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE); - ret = wait_for((I915_READ(ILK_GDSR) & - ILK_GRDOM_RESET_ENABLE) == 0, 500); + ret = intel_wait_for_register(dev_priv, + ILK_GDSR, ILK_GRDOM_RESET_ENABLE, 0, + 500); if (ret) return ret; @@ -1551,20 +1555,16 @@ static int ironlake_do_reset(struct drm_i915_private *dev_priv, static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv, u32 hw_domain_mask) { - int ret; - /* GEN6_GDRST is not in the gt power well, no need to check * for fifo space for the write or forcewake the chip for * the read */ __raw_i915_write32(dev_priv, GEN6_GDRST, hw_domain_mask); -#define ACKED ((__raw_i915_read32(dev_priv, GEN6_GDRST) & hw_domain_mask) == 0) /* Spin waiting for the device to ack the reset requests */ - ret = wait_for(ACKED, 500); -#undef ACKED - - return ret; + return intel_wait_for_register_fw(dev_priv, + GEN6_GDRST, hw_domain_mask, 0, + 500); } /** @@ -1609,13 +1609,74 @@ static int gen6_reset_engines(struct drm_i915_private *dev_priv, return ret; } -static int wait_for_register_fw(struct drm_i915_private *dev_priv, - i915_reg_t reg, - const u32 mask, - const u32 value, - const unsigned long timeout_ms) +/** + * intel_wait_for_register_fw - wait until register matches expected state + * @dev_priv: the i915 device + * @reg: the register to read + * @mask: mask to apply to register value + * @value: expected value + * @timeout_ms: timeout in millisecond + * + * This routine waits until the target register @reg contains the expected + * @value after applying the @mask, i.e. it waits until + * (I915_READ_FW(@reg) & @mask) == @value + * Otherwise, the wait will timeout after @timeout_ms milliseconds. + * + * Note that this routine assumes the caller holds forcewake asserted, it is + * not suitable for very long waits. See intel_wait_for_register() if you + * wish to wait without holding forcewake for the duration (i.e. you expect + * the wait to be slow). + * + * Returns 0 if the register matches the desired condition, or -ETIMEOUT. + */ +int intel_wait_for_register_fw(struct drm_i915_private *dev_priv, + i915_reg_t reg, + const u32 mask, + const u32 value, + const unsigned long timeout_ms) +{ +#define done ((I915_READ_FW(reg) & mask) == value) + int ret = wait_for_us(done, 2); + if (ret) + ret = wait_for(done, timeout_ms); + return ret; +#undef done +} + +/** + * intel_wait_for_register - wait until register matches expected state + * @dev_priv: the i915 device + * @reg: the register to read + * @mask: mask to apply to register value + * @value: expected value + * @timeout_ms: timeout in millisecond + * + * This routine waits until the target register @reg contains the expected + * @value after applying the @mask, i.e. it waits until + * (I915_READ(@reg) & @mask) == @value + * Otherwise, the wait will timeout after @timeout_ms milliseconds. + * + * Returns 0 if the register matches the desired condition, or -ETIMEOUT. + */ +int intel_wait_for_register(struct drm_i915_private *dev_priv, + i915_reg_t reg, + const u32 mask, + const u32 value, + const unsigned long timeout_ms) { - return wait_for((I915_READ_FW(reg) & mask) == value, timeout_ms); + + unsigned fw = + intel_uncore_forcewake_for_reg(dev_priv, reg, FW_REG_READ); + int ret; + + intel_uncore_forcewake_get(dev_priv, fw); + ret = wait_for_us((I915_READ_FW(reg) & mask) == value, 2); + intel_uncore_forcewake_put(dev_priv, fw); + if (ret) + ret = wait_for((I915_READ_NOTRACE(reg) & mask) == value, + timeout_ms); + + return ret; } static int gen8_request_engine_reset(struct intel_engine_cs *engine) @@ -1626,11 +1687,11 @@ static int gen8_request_engine_reset(struct intel_engine_cs *engine) I915_WRITE_FW(RING_RESET_CTL(engine->mmio_base), _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET)); - ret = wait_for_register_fw(dev_priv, - RING_RESET_CTL(engine->mmio_base), - RESET_CTL_READY_TO_RESET, - RESET_CTL_READY_TO_RESET, - 700); + ret = intel_wait_for_register_fw(dev_priv, + RING_RESET_CTL(engine->mmio_base), + RESET_CTL_READY_TO_RESET, + RESET_CTL_READY_TO_RESET, + 700); if (ret) DRM_ERROR("%s: reset request timeout\n", engine->name); |