diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 196 |
1 files changed, 83 insertions, 113 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 005b5e04de4d..3817a6f00d9e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -908,57 +908,63 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) | |||
908 | { | 908 | { |
909 | struct drm_device *dev = ring->dev; | 909 | struct drm_device *dev = ring->dev; |
910 | struct drm_i915_private *dev_priv = dev->dev_private; | 910 | struct drm_i915_private *dev_priv = dev->dev_private; |
911 | uint32_t tmp; | ||
911 | 912 | ||
912 | /* WaDisablePartialInstShootdown:skl */ | 913 | /* WaDisablePartialInstShootdown:skl,bxt */ |
913 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, | 914 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, |
914 | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); | 915 | PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE); |
915 | 916 | ||
916 | /* Syncing dependencies between camera and graphics */ | 917 | /* Syncing dependencies between camera and graphics:skl,bxt */ |
917 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, | 918 | WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, |
918 | GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); | 919 | GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC); |
919 | 920 | ||
920 | if (INTEL_REVID(dev) == SKL_REVID_A0 || | 921 | if ((IS_SKYLAKE(dev) && (INTEL_REVID(dev) == SKL_REVID_A0 || |
921 | INTEL_REVID(dev) == SKL_REVID_B0) { | 922 | INTEL_REVID(dev) == SKL_REVID_B0)) || |
922 | /* WaDisableDgMirrorFixInHalfSliceChicken5:skl */ | 923 | (IS_BROXTON(dev) && INTEL_REVID(dev) < BXT_REVID_B0)) { |
924 | /* WaDisableDgMirrorFixInHalfSliceChicken5:skl,bxt */ | ||
923 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, | 925 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, |
924 | GEN9_DG_MIRROR_FIX_ENABLE); | 926 | GEN9_DG_MIRROR_FIX_ENABLE); |
925 | } | 927 | } |
926 | 928 | ||
927 | if (IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_B0) { | 929 | if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_B0) || |
928 | /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:skl */ | 930 | (IS_BROXTON(dev) && INTEL_REVID(dev) < BXT_REVID_B0)) { |
931 | /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:skl,bxt */ | ||
929 | WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1, | 932 | WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1, |
930 | GEN9_RHWO_OPTIMIZATION_DISABLE); | 933 | GEN9_RHWO_OPTIMIZATION_DISABLE); |
931 | WA_SET_BIT_MASKED(GEN9_SLICE_COMMON_ECO_CHICKEN0, | 934 | WA_SET_BIT_MASKED(GEN9_SLICE_COMMON_ECO_CHICKEN0, |
932 | DISABLE_PIXEL_MASK_CAMMING); | 935 | DISABLE_PIXEL_MASK_CAMMING); |
933 | } | 936 | } |
934 | 937 | ||
935 | if (INTEL_REVID(dev) >= SKL_REVID_C0) { | 938 | if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) >= SKL_REVID_C0) || |
936 | /* WaEnableYV12BugFixInHalfSliceChicken7:skl */ | 939 | IS_BROXTON(dev)) { |
940 | /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt */ | ||
937 | WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, | 941 | WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, |
938 | GEN9_ENABLE_YV12_BUGFIX); | 942 | GEN9_ENABLE_YV12_BUGFIX); |
939 | } | 943 | } |
940 | 944 | ||
941 | if (INTEL_REVID(dev) <= SKL_REVID_D0) { | 945 | /* Wa4x4STCOptimizationDisable:skl,bxt */ |
942 | /* | ||
943 | *Use Force Non-Coherent whenever executing a 3D context. This | ||
944 | * is a workaround for a possible hang in the unlikely event | ||
945 | * a TLB invalidation occurs during a PSD flush. | ||
946 | */ | ||
947 | /* WaForceEnableNonCoherent:skl */ | ||
948 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | ||
949 | HDC_FORCE_NON_COHERENT); | ||
950 | } | ||
951 | |||
952 | /* Wa4x4STCOptimizationDisable:skl */ | ||
953 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); | 946 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE); |
954 | 947 | ||
955 | /* WaDisablePartialResolveInVc:skl */ | 948 | /* WaDisablePartialResolveInVc:skl,bxt */ |
956 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE); | 949 | WA_SET_BIT_MASKED(CACHE_MODE_1, GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE); |
957 | 950 | ||
958 | /* WaCcsTlbPrefetchDisable:skl */ | 951 | /* WaCcsTlbPrefetchDisable:skl,bxt */ |
959 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, | 952 | WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5, |
960 | GEN9_CCS_TLB_PREFETCH_ENABLE); | 953 | GEN9_CCS_TLB_PREFETCH_ENABLE); |
961 | 954 | ||
955 | /* WaDisableMaskBasedCammingInRCC:skl,bxt */ | ||
956 | if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) == SKL_REVID_C0) || | ||
957 | (IS_BROXTON(dev) && INTEL_REVID(dev) < BXT_REVID_B0)) | ||
958 | WA_SET_BIT_MASKED(SLICE_ECO_CHICKEN0, | ||
959 | PIXEL_MASK_CAMMING_DISABLE); | ||
960 | |||
961 | /* WaForceContextSaveRestoreNonCoherent:skl,bxt */ | ||
962 | tmp = HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT; | ||
963 | if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) == SKL_REVID_F0) || | ||
964 | (IS_BROXTON(dev) && INTEL_REVID(dev) >= BXT_REVID_B0)) | ||
965 | tmp |= HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE; | ||
966 | WA_SET_BIT_MASKED(HDC_CHICKEN0, tmp); | ||
967 | |||
962 | return 0; | 968 | return 0; |
963 | } | 969 | } |
964 | 970 | ||
@@ -1024,9 +1030,41 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) | |||
1024 | HDC_FENCE_DEST_SLM_DISABLE | | 1030 | HDC_FENCE_DEST_SLM_DISABLE | |
1025 | HDC_BARRIER_PERFORMANCE_DISABLE); | 1031 | HDC_BARRIER_PERFORMANCE_DISABLE); |
1026 | 1032 | ||
1033 | if (INTEL_REVID(dev) <= SKL_REVID_D0) { | ||
1034 | /* | ||
1035 | *Use Force Non-Coherent whenever executing a 3D context. This | ||
1036 | * is a workaround for a possible hang in the unlikely event | ||
1037 | * a TLB invalidation occurs during a PSD flush. | ||
1038 | */ | ||
1039 | /* WaForceEnableNonCoherent:skl */ | ||
1040 | WA_SET_BIT_MASKED(HDC_CHICKEN0, | ||
1041 | HDC_FORCE_NON_COHERENT); | ||
1042 | } | ||
1043 | |||
1027 | return skl_tune_iz_hashing(ring); | 1044 | return skl_tune_iz_hashing(ring); |
1028 | } | 1045 | } |
1029 | 1046 | ||
1047 | static int bxt_init_workarounds(struct intel_engine_cs *ring) | ||
1048 | { | ||
1049 | struct drm_device *dev = ring->dev; | ||
1050 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1051 | |||
1052 | gen9_init_workarounds(ring); | ||
1053 | |||
1054 | /* WaDisableThreadStallDopClockGating:bxt */ | ||
1055 | WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, | ||
1056 | STALL_DOP_GATING_DISABLE); | ||
1057 | |||
1058 | /* WaDisableSbeCacheDispatchPortSharing:bxt */ | ||
1059 | if (INTEL_REVID(dev) <= BXT_REVID_B0) { | ||
1060 | WA_SET_BIT_MASKED( | ||
1061 | GEN7_HALF_SLICE_CHICKEN1, | ||
1062 | GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); | ||
1063 | } | ||
1064 | |||
1065 | return 0; | ||
1066 | } | ||
1067 | |||
1030 | int init_workarounds_ring(struct intel_engine_cs *ring) | 1068 | int init_workarounds_ring(struct intel_engine_cs *ring) |
1031 | { | 1069 | { |
1032 | struct drm_device *dev = ring->dev; | 1070 | struct drm_device *dev = ring->dev; |
@@ -1044,8 +1082,9 @@ int init_workarounds_ring(struct intel_engine_cs *ring) | |||
1044 | 1082 | ||
1045 | if (IS_SKYLAKE(dev)) | 1083 | if (IS_SKYLAKE(dev)) |
1046 | return skl_init_workarounds(ring); | 1084 | return skl_init_workarounds(ring); |
1047 | else if (IS_GEN9(dev)) | 1085 | |
1048 | return gen9_init_workarounds(ring); | 1086 | if (IS_BROXTON(dev)) |
1087 | return bxt_init_workarounds(ring); | ||
1049 | 1088 | ||
1050 | return 0; | 1089 | return 0; |
1051 | } | 1090 | } |
@@ -1972,6 +2011,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
1972 | INIT_LIST_HEAD(&ring->active_list); | 2011 | INIT_LIST_HEAD(&ring->active_list); |
1973 | INIT_LIST_HEAD(&ring->request_list); | 2012 | INIT_LIST_HEAD(&ring->request_list); |
1974 | INIT_LIST_HEAD(&ring->execlist_queue); | 2013 | INIT_LIST_HEAD(&ring->execlist_queue); |
2014 | i915_gem_batch_pool_init(dev, &ring->batch_pool); | ||
1975 | ringbuf->size = 32 * PAGE_SIZE; | 2015 | ringbuf->size = 32 * PAGE_SIZE; |
1976 | ringbuf->ring = ring; | 2016 | ringbuf->ring = ring; |
1977 | memset(ring->semaphore.sync_seqno, 0, sizeof(ring->semaphore.sync_seqno)); | 2017 | memset(ring->semaphore.sync_seqno, 0, sizeof(ring->semaphore.sync_seqno)); |
@@ -2050,91 +2090,40 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) | |||
2050 | cleanup_status_page(ring); | 2090 | cleanup_status_page(ring); |
2051 | 2091 | ||
2052 | i915_cmd_parser_fini_ring(ring); | 2092 | i915_cmd_parser_fini_ring(ring); |
2093 | i915_gem_batch_pool_fini(&ring->batch_pool); | ||
2053 | 2094 | ||
2054 | kfree(ringbuf); | 2095 | kfree(ringbuf); |
2055 | ring->buffer = NULL; | 2096 | ring->buffer = NULL; |
2056 | } | 2097 | } |
2057 | 2098 | ||
2058 | static int intel_ring_wait_request(struct intel_engine_cs *ring, int n) | 2099 | static int ring_wait_for_space(struct intel_engine_cs *ring, int n) |
2059 | { | 2100 | { |
2060 | struct intel_ringbuffer *ringbuf = ring->buffer; | 2101 | struct intel_ringbuffer *ringbuf = ring->buffer; |
2061 | struct drm_i915_gem_request *request; | 2102 | struct drm_i915_gem_request *request; |
2103 | unsigned space; | ||
2062 | int ret; | 2104 | int ret; |
2063 | 2105 | ||
2064 | if (intel_ring_space(ringbuf) >= n) | 2106 | if (intel_ring_space(ringbuf) >= n) |
2065 | return 0; | 2107 | return 0; |
2066 | 2108 | ||
2067 | list_for_each_entry(request, &ring->request_list, list) { | 2109 | list_for_each_entry(request, &ring->request_list, list) { |
2068 | if (__intel_ring_space(request->postfix, ringbuf->tail, | 2110 | space = __intel_ring_space(request->postfix, ringbuf->tail, |
2069 | ringbuf->size) >= n) { | 2111 | ringbuf->size); |
2112 | if (space >= n) | ||
2070 | break; | 2113 | break; |
2071 | } | ||
2072 | } | 2114 | } |
2073 | 2115 | ||
2074 | if (&request->list == &ring->request_list) | 2116 | if (WARN_ON(&request->list == &ring->request_list)) |
2075 | return -ENOSPC; | 2117 | return -ENOSPC; |
2076 | 2118 | ||
2077 | ret = i915_wait_request(request); | 2119 | ret = i915_wait_request(request); |
2078 | if (ret) | 2120 | if (ret) |
2079 | return ret; | 2121 | return ret; |
2080 | 2122 | ||
2081 | i915_gem_retire_requests_ring(ring); | 2123 | ringbuf->space = space; |
2082 | |||
2083 | return 0; | 2124 | return 0; |
2084 | } | 2125 | } |
2085 | 2126 | ||
2086 | static int ring_wait_for_space(struct intel_engine_cs *ring, int n) | ||
2087 | { | ||
2088 | struct drm_device *dev = ring->dev; | ||
2089 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2090 | struct intel_ringbuffer *ringbuf = ring->buffer; | ||
2091 | unsigned long end; | ||
2092 | int ret; | ||
2093 | |||
2094 | ret = intel_ring_wait_request(ring, n); | ||
2095 | if (ret != -ENOSPC) | ||
2096 | return ret; | ||
2097 | |||
2098 | /* force the tail write in case we have been skipping them */ | ||
2099 | __intel_ring_advance(ring); | ||
2100 | |||
2101 | /* With GEM the hangcheck timer should kick us out of the loop, | ||
2102 | * leaving it early runs the risk of corrupting GEM state (due | ||
2103 | * to running on almost untested codepaths). But on resume | ||
2104 | * timers don't work yet, so prevent a complete hang in that | ||
2105 | * case by choosing an insanely large timeout. */ | ||
2106 | end = jiffies + 60 * HZ; | ||
2107 | |||
2108 | ret = 0; | ||
2109 | trace_i915_ring_wait_begin(ring); | ||
2110 | do { | ||
2111 | if (intel_ring_space(ringbuf) >= n) | ||
2112 | break; | ||
2113 | ringbuf->head = I915_READ_HEAD(ring); | ||
2114 | if (intel_ring_space(ringbuf) >= n) | ||
2115 | break; | ||
2116 | |||
2117 | msleep(1); | ||
2118 | |||
2119 | if (dev_priv->mm.interruptible && signal_pending(current)) { | ||
2120 | ret = -ERESTARTSYS; | ||
2121 | break; | ||
2122 | } | ||
2123 | |||
2124 | ret = i915_gem_check_wedge(&dev_priv->gpu_error, | ||
2125 | dev_priv->mm.interruptible); | ||
2126 | if (ret) | ||
2127 | break; | ||
2128 | |||
2129 | if (time_after(jiffies, end)) { | ||
2130 | ret = -EBUSY; | ||
2131 | break; | ||
2132 | } | ||
2133 | } while (1); | ||
2134 | trace_i915_ring_wait_end(ring); | ||
2135 | return ret; | ||
2136 | } | ||
2137 | |||
2138 | static int intel_wrap_ring_buffer(struct intel_engine_cs *ring) | 2127 | static int intel_wrap_ring_buffer(struct intel_engine_cs *ring) |
2139 | { | 2128 | { |
2140 | uint32_t __iomem *virt; | 2129 | uint32_t __iomem *virt; |
@@ -2175,38 +2164,19 @@ int intel_ring_idle(struct intel_engine_cs *ring) | |||
2175 | return 0; | 2164 | return 0; |
2176 | 2165 | ||
2177 | req = list_entry(ring->request_list.prev, | 2166 | req = list_entry(ring->request_list.prev, |
2178 | struct drm_i915_gem_request, | 2167 | struct drm_i915_gem_request, |
2179 | list); | 2168 | list); |
2180 | 2169 | ||
2181 | return i915_wait_request(req); | 2170 | /* Make sure we do not trigger any retires */ |
2171 | return __i915_wait_request(req, | ||
2172 | atomic_read(&to_i915(ring->dev)->gpu_error.reset_counter), | ||
2173 | to_i915(ring->dev)->mm.interruptible, | ||
2174 | NULL, NULL); | ||
2182 | } | 2175 | } |
2183 | 2176 | ||
2184 | static int | 2177 | int intel_ring_alloc_request_extras(struct drm_i915_gem_request *request) |
2185 | intel_ring_alloc_request(struct intel_engine_cs *ring) | ||
2186 | { | 2178 | { |
2187 | int ret; | 2179 | request->ringbuf = request->ring->buffer; |
2188 | struct drm_i915_gem_request *request; | ||
2189 | struct drm_i915_private *dev_private = ring->dev->dev_private; | ||
2190 | |||
2191 | if (ring->outstanding_lazy_request) | ||
2192 | return 0; | ||
2193 | |||
2194 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
2195 | if (request == NULL) | ||
2196 | return -ENOMEM; | ||
2197 | |||
2198 | kref_init(&request->ref); | ||
2199 | request->ring = ring; | ||
2200 | request->ringbuf = ring->buffer; | ||
2201 | request->uniq = dev_private->request_uniq++; | ||
2202 | |||
2203 | ret = i915_gem_get_seqno(ring->dev, &request->seqno); | ||
2204 | if (ret) { | ||
2205 | kfree(request); | ||
2206 | return ret; | ||
2207 | } | ||
2208 | |||
2209 | ring->outstanding_lazy_request = request; | ||
2210 | return 0; | 2180 | return 0; |
2211 | } | 2181 | } |
2212 | 2182 | ||
@@ -2247,7 +2217,7 @@ int intel_ring_begin(struct intel_engine_cs *ring, | |||
2247 | return ret; | 2217 | return ret; |
2248 | 2218 | ||
2249 | /* Preallocate the olr before touching the ring */ | 2219 | /* Preallocate the olr before touching the ring */ |
2250 | ret = intel_ring_alloc_request(ring); | 2220 | ret = i915_gem_request_alloc(ring, ring->default_context); |
2251 | if (ret) | 2221 | if (ret) |
2252 | return ret; | 2222 | return ret; |
2253 | 2223 | ||