aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ringbuffer.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-09-16 02:02:09 -0400
committerDave Airlie <airlied@redhat.com>2014-09-16 02:02:09 -0400
commit40d201af0b9e6196a210b97d3b2493b1156564f6 (patch)
tree687b212fd0d91f648551967aba12ce7dc8de5560 /drivers/gpu/drm/i915/intel_ringbuffer.c
parent29a7d1795a0376beee6c0f7515fae3789277e03e (diff)
parenta12624959ad4e3bfa8c344ad71728ffc9a379158 (diff)
Merge tag 'drm-intel-next-2014-09-05' of git://anongit.freedesktop.org/drm-intel into drm-next
- final bits (again) for the rotation support (Sonika Jindal) - support bl_power in the intel backlight (Jani) - vdd handling improvements from Ville - i830M fixes from Ville - piles of prep work all over to make skl enabling just plug in (Damien, Sonika) - rename DP training defines to reflect latest edp standards, this touches all drm drivers supporting DP (Sonika Jindal) - cache edids during single detect cycle to avoid re-reading it for e.g. audio, from Chris - move w/a for registers which are stored in the hw context to the context init code (Arun&Damien) - edp panel power sequencer fixes, helps chv a lot (Ville) - piles of other chv fixes all over - much more paranoid pageflip handling with stall detection and better recovery from Chris - small things all over, as usual * tag 'drm-intel-next-2014-09-05' of git://anongit.freedesktop.org/drm-intel: (114 commits) drm/i915: Update DRIVER_DATE to 20140905 drm/i915: Decouple the stuck pageflip on modeset drm/i915: Check for a stalled page flip after each vblank drm/i915: Introduce a for_each_plane() macro drm/i915: Rewrite ABS_DIFF() in a safer manner drm/i915: Add comments explaining the vdd on/off functions drm/i915: Move DP port disable to post_disable for pch platforms drm/i915: Enable DP port earlier drm/i915: Turn on panel power before doing aux transfers drm/i915: Be more careful when picking the initial power sequencer pipe drm/i915: Reset power sequencer pipe tracking when disp2d is off drm/i915: Track which port is using which pipe's power sequencer drm/i915: Fix edp vdd locking drm/i915: Reset the HEAD pointer for the ring after writing START drm/i915: Fix unsafe vma iteration in i915_drop_caches drm/i915: init sprites with univeral plane init function drm/i915: Check of !HAS_PCH_SPLIT() in PCH transcoder funcs drm/i915: Use HAS_GMCH_DISPLAY un underrun reporting code drm/i915: Use IS_BROADWELL() instead of IS_GEN8() in forcewake code drm/i915: Don't call gen8_fbc_sw_flush() on chv ...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c161
1 files changed, 160 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 3c7283d8f160..109de2eeb9a8 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -444,7 +444,14 @@ gen8_render_ring_flush(struct intel_engine_cs *ring,
444 return ret; 444 return ret;
445 } 445 }
446 446
447 return gen8_emit_pipe_control(ring, flags, scratch_addr); 447 ret = gen8_emit_pipe_control(ring, flags, scratch_addr);
448 if (ret)
449 return ret;
450
451 if (!invalidate_domains && flush_domains)
452 return gen7_ring_fbc_flush(ring, FBC_REND_NUKE);
453
454 return 0;
448} 455}
449 456
450static void ring_write_tail(struct intel_engine_cs *ring, 457static void ring_write_tail(struct intel_engine_cs *ring,
@@ -556,6 +563,14 @@ static int init_ring_common(struct intel_engine_cs *ring)
556 * also enforces ordering), otherwise the hw might lose the new ring 563 * also enforces ordering), otherwise the hw might lose the new ring
557 * register values. */ 564 * register values. */
558 I915_WRITE_START(ring, i915_gem_obj_ggtt_offset(obj)); 565 I915_WRITE_START(ring, i915_gem_obj_ggtt_offset(obj));
566
567 /* WaClearRingBufHeadRegAtInit:ctg,elk */
568 if (I915_READ_HEAD(ring))
569 DRM_DEBUG("%s initialization failed [head=%08x], fudging\n",
570 ring->name, I915_READ_HEAD(ring));
571 I915_WRITE_HEAD(ring, 0);
572 (void)I915_READ_HEAD(ring);
573
559 I915_WRITE_CTL(ring, 574 I915_WRITE_CTL(ring,
560 ((ringbuf->size - PAGE_SIZE) & RING_NR_PAGES) 575 ((ringbuf->size - PAGE_SIZE) & RING_NR_PAGES)
561 | RING_VALID); 576 | RING_VALID);
@@ -650,6 +665,146 @@ err:
650 return ret; 665 return ret;
651} 666}
652 667
668static inline void intel_ring_emit_wa(struct intel_engine_cs *ring,
669 u32 addr, u32 value)
670{
671 struct drm_device *dev = ring->dev;
672 struct drm_i915_private *dev_priv = dev->dev_private;
673
674 if (WARN_ON(dev_priv->num_wa_regs >= I915_MAX_WA_REGS))
675 return;
676
677 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
678 intel_ring_emit(ring, addr);
679 intel_ring_emit(ring, value);
680
681 dev_priv->intel_wa_regs[dev_priv->num_wa_regs].addr = addr;
682 dev_priv->intel_wa_regs[dev_priv->num_wa_regs].mask = value & 0xFFFF;
683 /* value is updated with the status of remaining bits of this
684 * register when it is read from debugfs file
685 */
686 dev_priv->intel_wa_regs[dev_priv->num_wa_regs].value = value;
687 dev_priv->num_wa_regs++;
688
689 return;
690}
691
692static int bdw_init_workarounds(struct intel_engine_cs *ring)
693{
694 int ret;
695 struct drm_device *dev = ring->dev;
696 struct drm_i915_private *dev_priv = dev->dev_private;
697
698 /*
699 * workarounds applied in this fn are part of register state context,
700 * they need to be re-initialized followed by gpu reset, suspend/resume,
701 * module reload.
702 */
703 dev_priv->num_wa_regs = 0;
704 memset(dev_priv->intel_wa_regs, 0, sizeof(dev_priv->intel_wa_regs));
705
706 /*
707 * update the number of dwords required based on the
708 * actual number of workarounds applied
709 */
710 ret = intel_ring_begin(ring, 24);
711 if (ret)
712 return ret;
713
714 /* WaDisablePartialInstShootdown:bdw */
715 /* WaDisableThreadStallDopClockGating:bdw */
716 /* FIXME: Unclear whether we really need this on production bdw. */
717 intel_ring_emit_wa(ring, GEN8_ROW_CHICKEN,
718 _MASKED_BIT_ENABLE(PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE
719 | STALL_DOP_GATING_DISABLE));
720
721 /* WaDisableDopClockGating:bdw May not be needed for production */
722 intel_ring_emit_wa(ring, GEN7_ROW_CHICKEN2,
723 _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
724
725 /*
726 * This GEN8_CENTROID_PIXEL_OPT_DIS W/A is only needed for
727 * pre-production hardware
728 */
729 intel_ring_emit_wa(ring, HALF_SLICE_CHICKEN3,
730 _MASKED_BIT_ENABLE(GEN8_CENTROID_PIXEL_OPT_DIS
731 | GEN8_SAMPLER_POWER_BYPASS_DIS));
732
733 intel_ring_emit_wa(ring, GEN7_HALF_SLICE_CHICKEN1,
734 _MASKED_BIT_ENABLE(GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE));
735
736 intel_ring_emit_wa(ring, COMMON_SLICE_CHICKEN2,
737 _MASKED_BIT_ENABLE(GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE));
738
739 /* Use Force Non-Coherent whenever executing a 3D context. This is a
740 * workaround for for a possible hang in the unlikely event a TLB
741 * invalidation occurs during a PSD flush.
742 */
743 intel_ring_emit_wa(ring, HDC_CHICKEN0,
744 _MASKED_BIT_ENABLE(HDC_FORCE_NON_COHERENT));
745
746 /* Wa4x4STCOptimizationDisable:bdw */
747 intel_ring_emit_wa(ring, CACHE_MODE_1,
748 _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE));
749
750 /*
751 * BSpec recommends 8x4 when MSAA is used,
752 * however in practice 16x4 seems fastest.
753 *
754 * Note that PS/WM thread counts depend on the WIZ hashing
755 * disable bit, which we don't touch here, but it's good
756 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
757 */
758 intel_ring_emit_wa(ring, GEN7_GT_MODE,
759 GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4);
760
761 intel_ring_advance(ring);
762
763 DRM_DEBUG_DRIVER("Number of Workarounds applied: %d\n",
764 dev_priv->num_wa_regs);
765
766 return 0;
767}
768
769static int chv_init_workarounds(struct intel_engine_cs *ring)
770{
771 int ret;
772 struct drm_device *dev = ring->dev;
773 struct drm_i915_private *dev_priv = dev->dev_private;
774
775 /*
776 * workarounds applied in this fn are part of register state context,
777 * they need to be re-initialized followed by gpu reset, suspend/resume,
778 * module reload.
779 */
780 dev_priv->num_wa_regs = 0;
781 memset(dev_priv->intel_wa_regs, 0, sizeof(dev_priv->intel_wa_regs));
782
783 ret = intel_ring_begin(ring, 12);
784 if (ret)
785 return ret;
786
787 /* WaDisablePartialInstShootdown:chv */
788 intel_ring_emit_wa(ring, GEN8_ROW_CHICKEN,
789 _MASKED_BIT_ENABLE(PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE));
790
791 /* WaDisableThreadStallDopClockGating:chv */
792 intel_ring_emit_wa(ring, GEN8_ROW_CHICKEN,
793 _MASKED_BIT_ENABLE(STALL_DOP_GATING_DISABLE));
794
795 /* WaDisableDopClockGating:chv (pre-production hw) */
796 intel_ring_emit_wa(ring, GEN7_ROW_CHICKEN2,
797 _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
798
799 /* WaDisableSamplerPowerBypass:chv (pre-production hw) */
800 intel_ring_emit_wa(ring, HALF_SLICE_CHICKEN3,
801 _MASKED_BIT_ENABLE(GEN8_SAMPLER_POWER_BYPASS_DIS));
802
803 intel_ring_advance(ring);
804
805 return 0;
806}
807
653static int init_render_ring(struct intel_engine_cs *ring) 808static int init_render_ring(struct intel_engine_cs *ring)
654{ 809{
655 struct drm_device *dev = ring->dev; 810 struct drm_device *dev = ring->dev;
@@ -2148,6 +2303,10 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
2148 dev_priv->semaphore_obj = obj; 2303 dev_priv->semaphore_obj = obj;
2149 } 2304 }
2150 } 2305 }
2306 if (IS_CHERRYVIEW(dev))
2307 ring->init_context = chv_init_workarounds;
2308 else
2309 ring->init_context = bdw_init_workarounds;
2151 ring->add_request = gen6_add_request; 2310 ring->add_request = gen6_add_request;
2152 ring->flush = gen8_render_ring_flush; 2311 ring->flush = gen8_render_ring_flush;
2153 ring->irq_get = gen8_ring_get_irq; 2312 ring->irq_get = gen8_ring_get_irq;