diff options
author | Dave Airlie <airlied@redhat.com> | 2014-09-16 02:02:09 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-09-16 02:02:09 -0400 |
commit | 40d201af0b9e6196a210b97d3b2493b1156564f6 (patch) | |
tree | 687b212fd0d91f648551967aba12ce7dc8de5560 /drivers/gpu/drm/i915/intel_ringbuffer.c | |
parent | 29a7d1795a0376beee6c0f7515fae3789277e03e (diff) | |
parent | a12624959ad4e3bfa8c344ad71728ffc9a379158 (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.c | 161 |
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 | ||
450 | static void ring_write_tail(struct intel_engine_cs *ring, | 457 | static 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 | ||
668 | static 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 | |||
692 | static 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 | |||
769 | static 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 | |||
653 | static int init_render_ring(struct intel_engine_cs *ring) | 808 | static 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; |