diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-10 12:33:06 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-10 12:33:06 -0500 |
commit | 3e82806b97398d542a5e03bd94861f79ce10ecee (patch) | |
tree | 467753d23d422fc42a07992ac25cae7889e48c18 /drivers/gpu/drm/i915/intel_ringbuffer.c | |
parent | bd4f203e433387d39be404b67ad02acf6f76b7bc (diff) | |
parent | 816d2206f0f9953ca854e4ff1a2749a5cbd62715 (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"I Was Almost Tempted To Capitalise Every Word, but then I decided I
couldn't read it myself!
I've also got one pull request for the sti driver outstanding. It
relied on a commit in Greg's tree and I didn't find out in time, that
commit is in your tree now so I might send that along once this is
merged.
I also had the accidental misfortune to have access to a Skylake on my
desk for a few days, and I've had to encourage Intel to try harder,
which seems to be happening now.
Here is the main drm-next pull request for 4.4.
Highlights:
New driver:
vc4 driver for the Rasberry Pi VPU.
(From Eric Anholt at Broadcom.)
Core:
Atomic fbdev support
Atomic helpers for runtime pm
dp/aux i2c STATUS_UPDATE handling
struct_mutex usage cleanups.
Generic of probing support.
Documentation:
Kerneldoc for VGA switcheroo code.
Rename to gpu instead of drm to reflect scope.
i915:
Skylake GuC firmware fixes
HPD A support
VBT backlight fallbacks
Fastboot by default for some systems
FBC work
BXT/SKL workarounds
Skylake deeper sleep state fixes
amdgpu:
Enable GPU scheduler by default
New atombios opcodes
GPUVM debugging options
Stoney support.
Fencing cleanups.
radeon:
More efficient CS checking
nouveau:
gk20a instance memory handling improvements.
Improved PGOB detection and GK107 support
Kepler GDDR5 PLL statbility improvement
G8x/GT2xx reclock improvements
new userspace API compatiblity fixes.
virtio-gpu:
Add 3D support - qemu 2.5 has it merged for it's gtk backend.
msm:
Initial msm88896 (snapdragon 8200)
exynos:
HDMI cleanups
Enable mixer driver byt default
Add DECON-TV support
vmwgfx:
Move to using memremap + fixes.
rcar-du:
Add support for R8A7793/4 DU
armada:
Remove support for non-component mode
Improved plane handling
Power savings while in DPMS off.
tda998x:
Remove unused slave encoder support
Use more HDMI helpers
Fix EDID read handling
dwhdmi:
Interlace video mode support for ipu-v3/dw_hdmi
Hotplug state fixes
Audio driver integration
imx:
More color formats support.
tegra:
Minor fixes/improvements"
[ Merge fixup: remove unused variable 'dev' that had all uses removed in
commit 4e270f088011: "drm/gem: Drop struct_mutex requirement from
drm_gem_mmap_obj" ]
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (764 commits)
drm/vmwgfx: Relax irq locking somewhat
drm/vmwgfx: Properly flush cursor updates and page-flips
drm/i915/skl: disable display side power well support for now
drm/i915: Extend DSL readout fix to BDW and SKL.
drm/i915: Do graphics device reset under forcewake
drm/i915: Skip fence installation for objects with rotated views (v4)
vga_switcheroo: Drop client power state VGA_SWITCHEROO_INIT
drm/amdgpu: group together common fence implementation
drm/amdgpu: remove AMDGPU_FENCE_OWNER_MOVE
drm/amdgpu: remove now unused fence functions
drm/amdgpu: fix fence fallback check
drm/amdgpu: fix stoping the scheduler timeout
drm/amdgpu: cleanup on error in amdgpu_cs_ioctl()
drm/i915: Fix locking around GuC firmware load
drm/amdgpu: update Fiji's Golden setting
drm/amdgpu: update Fiji's rev id
drm/amdgpu: extract common code in vi_common_early_init
drm/amd/scheduler: don't oops on failure to load
drm/amdgpu: don't oops on failure to load (v2)
drm/amdgpu: don't VT switch on suspend
...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 262 |
1 files changed, 160 insertions, 102 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 61b451fbd09e..9461a238f5d5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -719,7 +719,7 @@ static int intel_ring_workarounds_emit(struct drm_i915_gem_request *req) | |||
719 | struct drm_i915_private *dev_priv = dev->dev_private; | 719 | struct drm_i915_private *dev_priv = dev->dev_private; |
720 | struct i915_workarounds *w = &dev_priv->workarounds; | 720 | struct i915_workarounds *w = &dev_priv->workarounds; |
721 | 721 | ||
722 | if (WARN_ON_ONCE(w->count == 0)) | 722 | if (w->count == 0) |
723 | return 0; | 723 | return 0; |
724 | 724 | ||
725 | ring->gpu_caches_dirty = true; | 725 | ring->gpu_caches_dirty = true; |
@@ -802,42 +802,29 @@ static int wa_add(struct drm_i915_private *dev_priv, | |||
802 | 802 | ||
803 | #define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val) | 803 | #define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val) |
804 | 804 | ||
805 | static int bdw_init_workarounds(struct intel_engine_cs *ring) | 805 | static int gen8_init_workarounds(struct intel_engine_cs *ring) |
806 | { | 806 | { |
807 | struct drm_device *dev = ring->dev; | 807 | struct drm_device *dev = ring->dev; |
808 | struct drm_i915_private *dev_priv = dev->dev_private; | 808 | struct drm_i915_private *dev_priv = dev->dev_private; |
809 | 809 | ||
810 | WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); | 810 | WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); |
811 | 811 | ||
812 | /* WaDisableAsyncFlipPerfMode:bdw */ | 812 | /* WaDisableAsyncFlipPerfMode:bdw,chv */ |
813 | WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE); | 813 | WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE); |
814 | 814 | ||
815 | /* WaDisablePartialInstShootdown:bdw */ | 815 | /* WaDisablePartialInstShootdown:bdw,chv */ |
816 | /* WaDisableThreadStallDopClockGating:bdw (pre-production) */ | ||
817 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, | 816 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, |
818 | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE | | 817 | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); |
819 | STALL_DOP_GATING_DISABLE); | ||
820 | |||
821 | /* WaDisableDopClockGating:bdw */ | ||
822 | WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, | ||
823 | DOP_CLOCK_GATING_DISABLE); | ||
824 | |||
825 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, | ||
826 | GEN8_SAMPLER_POWER_BYPASS_DIS); | ||
827 | 818 | ||
828 | /* Use Force Non-Coherent whenever executing a 3D context. This is a | 819 | /* Use Force Non-Coherent whenever executing a 3D context. This is a |
829 | * workaround for for a possible hang in the unlikely event a TLB | 820 | * workaround for for a possible hang in the unlikely event a TLB |
830 | * invalidation occurs during a PSD flush. | 821 | * invalidation occurs during a PSD flush. |
831 | */ | 822 | */ |
823 | /* WaForceEnableNonCoherent:bdw,chv */ | ||
824 | /* WaHdcDisableFetchWhenMasked:bdw,chv */ | ||
832 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | 825 | WA_SET_BIT_MASKED(HDC_CHICKEN0, |
833 | /* WaForceEnableNonCoherent:bdw */ | ||
834 | HDC_FORCE_NON_COHERENT | | ||
835 | /* WaForceContextSaveRestoreNonCoherent:bdw */ | ||
836 | HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | | ||
837 | /* WaHdcDisableFetchWhenMasked:bdw */ | ||
838 | HDC_DONOT_FETCH_MEM_WHEN_MASKED | | 826 | HDC_DONOT_FETCH_MEM_WHEN_MASKED | |
839 | /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */ | 827 | HDC_FORCE_NON_COHERENT); |
840 | (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); | ||
841 | 828 | ||
842 | /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0: | 829 | /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0: |
843 | * "The Hierarchical Z RAW Stall Optimization allows non-overlapping | 830 | * "The Hierarchical Z RAW Stall Optimization allows non-overlapping |
@@ -845,13 +832,12 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) | |||
845 | * stalling waiting for the earlier ones to write to Hierarchical Z | 832 | * stalling waiting for the earlier ones to write to Hierarchical Z |
846 | * buffer." | 833 | * buffer." |
847 | * | 834 | * |
848 | * This optimization is off by default for Broadwell; turn it on. | 835 | * This optimization is off by default for BDW and CHV; turn it on. |
849 | */ | 836 | */ |
850 | WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); | 837 | WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); |
851 | 838 | ||
852 | /* Wa4x4STCOptimizationDisable:bdw */ | 839 | /* Wa4x4STCOptimizationDisable:bdw,chv */ |
853 | WA_SET_BIT_MASKED(CACHE_MODE_1, | 840 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); |
854 | GEN8_4x4_STC_OPTIMIZATION_DISABLE); | ||
855 | 841 | ||
856 | /* | 842 | /* |
857 | * BSpec recommends 8x4 when MSAA is used, | 843 | * BSpec recommends 8x4 when MSAA is used, |
@@ -868,56 +854,51 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) | |||
868 | return 0; | 854 | return 0; |
869 | } | 855 | } |
870 | 856 | ||
871 | static int chv_init_workarounds(struct intel_engine_cs *ring) | 857 | static int bdw_init_workarounds(struct intel_engine_cs *ring) |
872 | { | 858 | { |
859 | int ret; | ||
873 | struct drm_device *dev = ring->dev; | 860 | struct drm_device *dev = ring->dev; |
874 | struct drm_i915_private *dev_priv = dev->dev_private; | 861 | struct drm_i915_private *dev_priv = dev->dev_private; |
875 | 862 | ||
876 | WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); | 863 | ret = gen8_init_workarounds(ring); |
864 | if (ret) | ||
865 | return ret; | ||
877 | 866 | ||
878 | /* WaDisableAsyncFlipPerfMode:chv */ | 867 | /* WaDisableThreadStallDopClockGating:bdw (pre-production) */ |
879 | WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE); | 868 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE); |
880 | 869 | ||
881 | /* WaDisablePartialInstShootdown:chv */ | 870 | /* WaDisableDopClockGating:bdw */ |
882 | /* WaDisableThreadStallDopClockGating:chv */ | 871 | WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, |
883 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, | 872 | DOP_CLOCK_GATING_DISABLE); |
884 | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE | | 873 | |
885 | STALL_DOP_GATING_DISABLE); | 874 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, |
875 | GEN8_SAMPLER_POWER_BYPASS_DIS); | ||
886 | 876 | ||
887 | /* Use Force Non-Coherent whenever executing a 3D context. This is a | ||
888 | * workaround for a possible hang in the unlikely event a TLB | ||
889 | * invalidation occurs during a PSD flush. | ||
890 | */ | ||
891 | /* WaForceEnableNonCoherent:chv */ | ||
892 | /* WaHdcDisableFetchWhenMasked:chv */ | ||
893 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | 877 | WA_SET_BIT_MASKED(HDC_CHICKEN0, |
894 | HDC_FORCE_NON_COHERENT | | 878 | /* WaForceContextSaveRestoreNonCoherent:bdw */ |
895 | HDC_DONOT_FETCH_MEM_WHEN_MASKED); | 879 | HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT | |
880 | /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */ | ||
881 | (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); | ||
896 | 882 | ||
897 | /* According to the CACHE_MODE_0 default value documentation, some | 883 | return 0; |
898 | * CHV platforms disable this optimization by default. Turn it on. | 884 | } |
899 | */ | ||
900 | WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); | ||
901 | 885 | ||
902 | /* Wa4x4STCOptimizationDisable:chv */ | 886 | static int chv_init_workarounds(struct intel_engine_cs *ring) |
903 | WA_SET_BIT_MASKED(CACHE_MODE_1, | 887 | { |
904 | GEN8_4x4_STC_OPTIMIZATION_DISABLE); | 888 | int ret; |
889 | struct drm_device *dev = ring->dev; | ||
890 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
891 | |||
892 | ret = gen8_init_workarounds(ring); | ||
893 | if (ret) | ||
894 | return ret; | ||
895 | |||
896 | /* WaDisableThreadStallDopClockGating:chv */ | ||
897 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE); | ||
905 | 898 | ||
906 | /* Improve HiZ throughput on CHV. */ | 899 | /* Improve HiZ throughput on CHV. */ |
907 | WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X); | 900 | WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X); |
908 | 901 | ||
909 | /* | ||
910 | * BSpec recommends 8x4 when MSAA is used, | ||
911 | * however in practice 16x4 seems fastest. | ||
912 | * | ||
913 | * Note that PS/WM thread counts depend on the WIZ hashing | ||
914 | * disable bit, which we don't touch here, but it's good | ||
915 | * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). | ||
916 | */ | ||
917 | WA_SET_FIELD_MASKED(GEN7_GT_MODE, | ||
918 | GEN6_WIZ_HASHING_MASK, | ||
919 | GEN6_WIZ_HASHING_16x4); | ||
920 | |||
921 | return 0; | 902 | return 0; |
922 | } | 903 | } |
923 | 904 | ||
@@ -927,6 +908,14 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) | |||
927 | struct drm_i915_private *dev_priv = dev->dev_private; | 908 | struct drm_i915_private *dev_priv = dev->dev_private; |
928 | uint32_t tmp; | 909 | uint32_t tmp; |
929 | 910 | ||
911 | /* WaEnableLbsSlaRetryTimerDecrement:skl */ | ||
912 | I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | | ||
913 | GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); | ||
914 | |||
915 | /* WaDisableKillLogic:bxt,skl */ | ||
916 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | | ||
917 | ECOCHK_DIS_TLB); | ||
918 | |||
930 | /* WaDisablePartialInstShootdown:skl,bxt */ | 919 | /* WaDisablePartialInstShootdown:skl,bxt */ |
931 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, | 920 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, |
932 | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); | 921 | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); |
@@ -963,10 +952,9 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) | |||
963 | } | 952 | } |
964 | 953 | ||
965 | /* Wa4x4STCOptimizationDisable:skl,bxt */ | 954 | /* Wa4x4STCOptimizationDisable:skl,bxt */ |
966 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); | ||
967 | |||
968 | /* WaDisablePartialResolveInVc:skl,bxt */ | 955 | /* WaDisablePartialResolveInVc:skl,bxt */ |
969 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE); | 956 | WA_SET_BIT_MASKED(CACHE_MODE_1, (GEN8_4x4_STC_OPTIMIZATION_DISABLE | |
957 | GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE)); | ||
970 | 958 | ||
971 | /* WaCcsTlbPrefetchDisable:skl,bxt */ | 959 | /* WaCcsTlbPrefetchDisable:skl,bxt */ |
972 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, | 960 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, |
@@ -985,6 +973,16 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) | |||
985 | tmp |= HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE; | 973 | tmp |= HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE; |
986 | WA_SET_BIT_MASKED(HDC_CHICKEN0, tmp); | 974 | WA_SET_BIT_MASKED(HDC_CHICKEN0, tmp); |
987 | 975 | ||
976 | /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt */ | ||
977 | if (IS_SKYLAKE(dev) || | ||
978 | (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_B0)) { | ||
979 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, | ||
980 | GEN8_SAMPLER_POWER_BYPASS_DIS); | ||
981 | } | ||
982 | |||
983 | /* WaDisableSTUnitPowerOptimization:skl,bxt */ | ||
984 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE); | ||
985 | |||
988 | return 0; | 986 | return 0; |
989 | } | 987 | } |
990 | 988 | ||
@@ -1030,13 +1028,39 @@ static int skl_tune_iz_hashing(struct intel_engine_cs *ring) | |||
1030 | return 0; | 1028 | return 0; |
1031 | } | 1029 | } |
1032 | 1030 | ||
1033 | |||
1034 | static int skl_init_workarounds(struct intel_engine_cs *ring) | 1031 | static int skl_init_workarounds(struct intel_engine_cs *ring) |
1035 | { | 1032 | { |
1033 | int ret; | ||
1036 | struct drm_device *dev = ring->dev; | 1034 | struct drm_device *dev = ring->dev; |
1037 | struct drm_i915_private *dev_priv = dev->dev_private; | 1035 | struct drm_i915_private *dev_priv = dev->dev_private; |
1038 | 1036 | ||
1039 | gen9_init_workarounds(ring); | 1037 | ret = gen9_init_workarounds(ring); |
1038 | if (ret) | ||
1039 | return ret; | ||
1040 | |||
1041 | if (INTEL_REVID(dev) <= SKL_REVID_D0) { | ||
1042 | /* WaDisableHDCInvalidation:skl */ | ||
1043 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | | ||
1044 | BDW_DISABLE_HDC_INVALIDATION); | ||
1045 | |||
1046 | /* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */ | ||
1047 | I915_WRITE(FF_SLICE_CS_CHICKEN2, | ||
1048 | _MASKED_BIT_ENABLE(GEN9_TSG_BARRIER_ACK_DISABLE)); | ||
1049 | } | ||
1050 | |||
1051 | /* GEN8_L3SQCREG4 has a dependency with WA batch so any new changes | ||
1052 | * involving this register should also be added to WA batch as required. | ||
1053 | */ | ||
1054 | if (INTEL_REVID(dev) <= SKL_REVID_E0) | ||
1055 | /* WaDisableLSQCROPERFforOCL:skl */ | ||
1056 | I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | | ||
1057 | GEN8_LQSC_RO_PERF_DIS); | ||
1058 | |||
1059 | /* WaEnableGapsTsvCreditFix:skl */ | ||
1060 | if (IS_SKYLAKE(dev) && (INTEL_REVID(dev) >= SKL_REVID_C0)) { | ||
1061 | I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) | | ||
1062 | GEN9_GAPS_TSV_CREDIT_DISABLE)); | ||
1063 | } | ||
1040 | 1064 | ||
1041 | /* WaDisablePowerCompilerClockGating:skl */ | 1065 | /* WaDisablePowerCompilerClockGating:skl */ |
1042 | if (INTEL_REVID(dev) == SKL_REVID_B0) | 1066 | if (INTEL_REVID(dev) == SKL_REVID_B0) |
@@ -1073,10 +1097,24 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) | |||
1073 | 1097 | ||
1074 | static int bxt_init_workarounds(struct intel_engine_cs *ring) | 1098 | static int bxt_init_workarounds(struct intel_engine_cs *ring) |
1075 | { | 1099 | { |
1100 | int ret; | ||
1076 | struct drm_device *dev = ring->dev; | 1101 | struct drm_device *dev = ring->dev; |
1077 | struct drm_i915_private *dev_priv = dev->dev_private; | 1102 | struct drm_i915_private *dev_priv = dev->dev_private; |
1078 | 1103 | ||
1079 | gen9_init_workarounds(ring); | 1104 | ret = gen9_init_workarounds(ring); |
1105 | if (ret) | ||
1106 | return ret; | ||
1107 | |||
1108 | /* WaStoreMultiplePTEenable:bxt */ | ||
1109 | /* This is a requirement according to Hardware specification */ | ||
1110 | if (INTEL_REVID(dev) == BXT_REVID_A0) | ||
1111 | I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF); | ||
1112 | |||
1113 | /* WaSetClckGatingDisableMedia:bxt */ | ||
1114 | if (INTEL_REVID(dev) == BXT_REVID_A0) { | ||
1115 | I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) & | ||
1116 | ~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE)); | ||
1117 | } | ||
1080 | 1118 | ||
1081 | /* WaDisableThreadStallDopClockGating:bxt */ | 1119 | /* WaDisableThreadStallDopClockGating:bxt */ |
1082 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, | 1120 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, |
@@ -1998,14 +2036,14 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, | |||
1998 | return 0; | 2036 | return 0; |
1999 | } | 2037 | } |
2000 | 2038 | ||
2001 | void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) | 2039 | static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) |
2002 | { | 2040 | { |
2003 | drm_gem_object_unreference(&ringbuf->obj->base); | 2041 | drm_gem_object_unreference(&ringbuf->obj->base); |
2004 | ringbuf->obj = NULL; | 2042 | ringbuf->obj = NULL; |
2005 | } | 2043 | } |
2006 | 2044 | ||
2007 | int intel_alloc_ringbuffer_obj(struct drm_device *dev, | 2045 | static int intel_alloc_ringbuffer_obj(struct drm_device *dev, |
2008 | struct intel_ringbuffer *ringbuf) | 2046 | struct intel_ringbuffer *ringbuf) |
2009 | { | 2047 | { |
2010 | struct drm_i915_gem_object *obj; | 2048 | struct drm_i915_gem_object *obj; |
2011 | 2049 | ||
@@ -2025,6 +2063,48 @@ int intel_alloc_ringbuffer_obj(struct drm_device *dev, | |||
2025 | return 0; | 2063 | return 0; |
2026 | } | 2064 | } |
2027 | 2065 | ||
2066 | struct intel_ringbuffer * | ||
2067 | intel_engine_create_ringbuffer(struct intel_engine_cs *engine, int size) | ||
2068 | { | ||
2069 | struct intel_ringbuffer *ring; | ||
2070 | int ret; | ||
2071 | |||
2072 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); | ||
2073 | if (ring == NULL) | ||
2074 | return ERR_PTR(-ENOMEM); | ||
2075 | |||
2076 | ring->ring = engine; | ||
2077 | |||
2078 | ring->size = size; | ||
2079 | /* Workaround an erratum on the i830 which causes a hang if | ||
2080 | * the TAIL pointer points to within the last 2 cachelines | ||
2081 | * of the buffer. | ||
2082 | */ | ||
2083 | ring->effective_size = size; | ||
2084 | if (IS_I830(engine->dev) || IS_845G(engine->dev)) | ||
2085 | ring->effective_size -= 2 * CACHELINE_BYTES; | ||
2086 | |||
2087 | ring->last_retired_head = -1; | ||
2088 | intel_ring_update_space(ring); | ||
2089 | |||
2090 | ret = intel_alloc_ringbuffer_obj(engine->dev, ring); | ||
2091 | if (ret) { | ||
2092 | DRM_ERROR("Failed to allocate ringbuffer %s: %d\n", | ||
2093 | engine->name, ret); | ||
2094 | kfree(ring); | ||
2095 | return ERR_PTR(ret); | ||
2096 | } | ||
2097 | |||
2098 | return ring; | ||
2099 | } | ||
2100 | |||
2101 | void | ||
2102 | intel_ringbuffer_free(struct intel_ringbuffer *ring) | ||
2103 | { | ||
2104 | intel_destroy_ringbuffer_obj(ring); | ||
2105 | kfree(ring); | ||
2106 | } | ||
2107 | |||
2028 | static int intel_init_ring_buffer(struct drm_device *dev, | 2108 | static int intel_init_ring_buffer(struct drm_device *dev, |
2029 | struct intel_engine_cs *ring) | 2109 | struct intel_engine_cs *ring) |
2030 | { | 2110 | { |
@@ -2033,22 +2113,20 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
2033 | 2113 | ||
2034 | WARN_ON(ring->buffer); | 2114 | WARN_ON(ring->buffer); |
2035 | 2115 | ||
2036 | ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL); | ||
2037 | if (!ringbuf) | ||
2038 | return -ENOMEM; | ||
2039 | ring->buffer = ringbuf; | ||
2040 | |||
2041 | ring->dev = dev; | 2116 | ring->dev = dev; |
2042 | INIT_LIST_HEAD(&ring->active_list); | 2117 | INIT_LIST_HEAD(&ring->active_list); |
2043 | INIT_LIST_HEAD(&ring->request_list); | 2118 | INIT_LIST_HEAD(&ring->request_list); |
2044 | INIT_LIST_HEAD(&ring->execlist_queue); | 2119 | INIT_LIST_HEAD(&ring->execlist_queue); |
2045 | i915_gem_batch_pool_init(dev, &ring->batch_pool); | 2120 | i915_gem_batch_pool_init(dev, &ring->batch_pool); |
2046 | ringbuf->size = 32 * PAGE_SIZE; | ||
2047 | ringbuf->ring = ring; | ||
2048 | memset(ring->semaphore.sync_seqno, 0, sizeof(ring->semaphore.sync_seqno)); | 2121 | memset(ring->semaphore.sync_seqno, 0, sizeof(ring->semaphore.sync_seqno)); |
2049 | 2122 | ||
2050 | init_waitqueue_head(&ring->irq_queue); | 2123 | init_waitqueue_head(&ring->irq_queue); |
2051 | 2124 | ||
2125 | ringbuf = intel_engine_create_ringbuffer(ring, 32 * PAGE_SIZE); | ||
2126 | if (IS_ERR(ringbuf)) | ||
2127 | return PTR_ERR(ringbuf); | ||
2128 | ring->buffer = ringbuf; | ||
2129 | |||
2052 | if (I915_NEED_GFX_HWS(dev)) { | 2130 | if (I915_NEED_GFX_HWS(dev)) { |
2053 | ret = init_status_page(ring); | 2131 | ret = init_status_page(ring); |
2054 | if (ret) | 2132 | if (ret) |
@@ -2060,15 +2138,6 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
2060 | goto error; | 2138 | goto error; |
2061 | } | 2139 | } |
2062 | 2140 | ||
2063 | WARN_ON(ringbuf->obj); | ||
2064 | |||
2065 | ret = intel_alloc_ringbuffer_obj(dev, ringbuf); | ||
2066 | if (ret) { | ||
2067 | DRM_ERROR("Failed to allocate ringbuffer %s: %d\n", | ||
2068 | ring->name, ret); | ||
2069 | goto error; | ||
2070 | } | ||
2071 | |||
2072 | ret = intel_pin_and_map_ringbuffer_obj(dev, ringbuf); | 2141 | ret = intel_pin_and_map_ringbuffer_obj(dev, ringbuf); |
2073 | if (ret) { | 2142 | if (ret) { |
2074 | DRM_ERROR("Failed to pin and map ringbuffer %s: %d\n", | 2143 | DRM_ERROR("Failed to pin and map ringbuffer %s: %d\n", |
@@ -2077,14 +2146,6 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
2077 | goto error; | 2146 | goto error; |
2078 | } | 2147 | } |
2079 | 2148 | ||
2080 | /* Workaround an erratum on the i830 which causes a hang if | ||
2081 | * the TAIL pointer points to within the last 2 cachelines | ||
2082 | * of the buffer. | ||
2083 | */ | ||
2084 | ringbuf->effective_size = ringbuf->size; | ||
2085 | if (IS_I830(dev) || IS_845G(dev)) | ||
2086 | ringbuf->effective_size -= 2 * CACHELINE_BYTES; | ||
2087 | |||
2088 | ret = i915_cmd_parser_init_ring(ring); | 2149 | ret = i915_cmd_parser_init_ring(ring); |
2089 | if (ret) | 2150 | if (ret) |
2090 | goto error; | 2151 | goto error; |
@@ -2092,7 +2153,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
2092 | return 0; | 2153 | return 0; |
2093 | 2154 | ||
2094 | error: | 2155 | error: |
2095 | kfree(ringbuf); | 2156 | intel_ringbuffer_free(ringbuf); |
2096 | ring->buffer = NULL; | 2157 | ring->buffer = NULL; |
2097 | return ret; | 2158 | return ret; |
2098 | } | 2159 | } |
@@ -2100,19 +2161,18 @@ error: | |||
2100 | void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) | 2161 | void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) |
2101 | { | 2162 | { |
2102 | struct drm_i915_private *dev_priv; | 2163 | struct drm_i915_private *dev_priv; |
2103 | struct intel_ringbuffer *ringbuf; | ||
2104 | 2164 | ||
2105 | if (!intel_ring_initialized(ring)) | 2165 | if (!intel_ring_initialized(ring)) |
2106 | return; | 2166 | return; |
2107 | 2167 | ||
2108 | dev_priv = to_i915(ring->dev); | 2168 | dev_priv = to_i915(ring->dev); |
2109 | ringbuf = ring->buffer; | ||
2110 | 2169 | ||
2111 | intel_stop_ring_buffer(ring); | 2170 | intel_stop_ring_buffer(ring); |
2112 | WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0); | 2171 | WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0); |
2113 | 2172 | ||
2114 | intel_unpin_ringbuffer_obj(ringbuf); | 2173 | intel_unpin_ringbuffer_obj(ring->buffer); |
2115 | intel_destroy_ringbuffer_obj(ringbuf); | 2174 | intel_ringbuffer_free(ring->buffer); |
2175 | ring->buffer = NULL; | ||
2116 | 2176 | ||
2117 | if (ring->cleanup) | 2177 | if (ring->cleanup) |
2118 | ring->cleanup(ring); | 2178 | ring->cleanup(ring); |
@@ -2121,9 +2181,6 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) | |||
2121 | 2181 | ||
2122 | i915_cmd_parser_fini_ring(ring); | 2182 | i915_cmd_parser_fini_ring(ring); |
2123 | i915_gem_batch_pool_fini(&ring->batch_pool); | 2183 | i915_gem_batch_pool_fini(&ring->batch_pool); |
2124 | |||
2125 | kfree(ringbuf); | ||
2126 | ring->buffer = NULL; | ||
2127 | } | 2184 | } |
2128 | 2185 | ||
2129 | static int ring_wait_for_space(struct intel_engine_cs *ring, int n) | 2186 | static int ring_wait_for_space(struct intel_engine_cs *ring, int n) |
@@ -2610,6 +2667,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
2610 | GEN8_RING_SEMAPHORE_INIT; | 2667 | GEN8_RING_SEMAPHORE_INIT; |
2611 | } | 2668 | } |
2612 | } else if (INTEL_INFO(dev)->gen >= 6) { | 2669 | } else if (INTEL_INFO(dev)->gen >= 6) { |
2670 | ring->init_context = intel_rcs_ctx_init; | ||
2613 | ring->add_request = gen6_add_request; | 2671 | ring->add_request = gen6_add_request; |
2614 | ring->flush = gen7_render_ring_flush; | 2672 | ring->flush = gen7_render_ring_flush; |
2615 | if (INTEL_INFO(dev)->gen == 6) | 2673 | if (INTEL_INFO(dev)->gen == 6) |