Rev 4293 | Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4104 | Serge | 1 | /* |
2 | * Copyright © 2013 Intel Corporation |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
5 | * copy of this software and associated documentation files (the "Software"), |
||
6 | * to deal in the Software without restriction, including without limitation |
||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
8 | * and/or sell copies of the Software, and to permit persons to whom the |
||
9 | * Software is furnished to do so, subject to the following conditions: |
||
10 | * |
||
11 | * The above copyright notice and this permission notice (including the next |
||
12 | * paragraph) shall be included in all copies or substantial portions of the |
||
13 | * Software. |
||
14 | * |
||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||
21 | * IN THE SOFTWARE. |
||
22 | */ |
||
23 | |||
24 | #include "i915_drv.h" |
||
25 | #include "intel_drv.h" |
||
26 | |||
27 | #define FORCEWAKE_ACK_TIMEOUT_MS 2 |
||
28 | |||
29 | #define __raw_i915_read8(dev_priv__, reg__) readb((dev_priv__)->regs + (reg__)) |
||
30 | #define __raw_i915_write8(dev_priv__, reg__, val__) writeb(val__, (dev_priv__)->regs + (reg__)) |
||
31 | |||
32 | #define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__)) |
||
33 | #define __raw_i915_write16(dev_priv__, reg__, val__) writew(val__, (dev_priv__)->regs + (reg__)) |
||
34 | |||
35 | #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) |
||
36 | #define __raw_i915_write32(dev_priv__, reg__, val__) writel(val__, (dev_priv__)->regs + (reg__)) |
||
37 | |||
38 | #define __raw_i915_read64(dev_priv__, reg__) readq((dev_priv__)->regs + (reg__)) |
||
39 | #define __raw_i915_write64(dev_priv__, reg__, val__) writeq(val__, (dev_priv__)->regs + (reg__)) |
||
40 | |||
41 | #define __raw_posting_read(dev_priv__, reg__) (void)__raw_i915_read32(dev_priv__, reg__) |
||
42 | |||
43 | |||
44 | static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) |
||
45 | { |
||
46 | u32 gt_thread_status_mask; |
||
47 | |||
48 | if (IS_HASWELL(dev_priv->dev)) |
||
49 | gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK_HSW; |
||
50 | else |
||
51 | gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK; |
||
52 | |||
53 | /* w/a for a sporadic read returning 0 by waiting for the GT |
||
54 | * thread to wake up. |
||
55 | */ |
||
56 | if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500)) |
||
57 | DRM_ERROR("GT thread status wait timed out\n"); |
||
58 | } |
||
59 | |||
60 | static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv) |
||
61 | { |
||
62 | __raw_i915_write32(dev_priv, FORCEWAKE, 0); |
||
63 | /* something from same cacheline, but !FORCEWAKE */ |
||
64 | __raw_posting_read(dev_priv, ECOBUS); |
||
65 | } |
||
66 | |||
67 | static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) |
||
68 | { |
||
69 | if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1) == 0, |
||
70 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
71 | DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); |
||
72 | |||
73 | __raw_i915_write32(dev_priv, FORCEWAKE, 1); |
||
74 | /* something from same cacheline, but !FORCEWAKE */ |
||
75 | __raw_posting_read(dev_priv, ECOBUS); |
||
76 | |||
77 | if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1), |
||
78 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
79 | DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); |
||
80 | |||
81 | /* WaRsForcewakeWaitTC0:snb */ |
||
82 | __gen6_gt_wait_for_thread_c0(dev_priv); |
||
83 | } |
||
84 | |||
85 | static void __gen6_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv) |
||
86 | { |
||
87 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff)); |
||
88 | /* something from same cacheline, but !FORCEWAKE_MT */ |
||
89 | __raw_posting_read(dev_priv, ECOBUS); |
||
90 | } |
||
91 | |||
92 | static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) |
||
93 | { |
||
94 | u32 forcewake_ack; |
||
95 | |||
96 | if (IS_HASWELL(dev_priv->dev)) |
||
97 | forcewake_ack = FORCEWAKE_ACK_HSW; |
||
98 | else |
||
99 | forcewake_ack = FORCEWAKE_MT_ACK; |
||
100 | |||
101 | if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL) == 0, |
||
102 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
103 | DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); |
||
104 | |||
105 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, |
||
106 | _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); |
||
107 | /* something from same cacheline, but !FORCEWAKE_MT */ |
||
108 | __raw_posting_read(dev_priv, ECOBUS); |
||
109 | |||
110 | if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL), |
||
111 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
112 | DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); |
||
113 | |||
114 | /* WaRsForcewakeWaitTC0:ivb,hsw */ |
||
115 | __gen6_gt_wait_for_thread_c0(dev_priv); |
||
116 | } |
||
117 | |||
118 | static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) |
||
119 | { |
||
120 | u32 gtfifodbg; |
||
121 | |||
122 | gtfifodbg = __raw_i915_read32(dev_priv, GTFIFODBG); |
||
123 | if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK, |
||
124 | "MMIO read or write has been dropped %x\n", gtfifodbg)) |
||
125 | __raw_i915_write32(dev_priv, GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); |
||
126 | } |
||
127 | |||
128 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
||
129 | { |
||
130 | __raw_i915_write32(dev_priv, FORCEWAKE, 0); |
||
131 | /* something from same cacheline, but !FORCEWAKE */ |
||
132 | __raw_posting_read(dev_priv, ECOBUS); |
||
133 | gen6_gt_check_fifodbg(dev_priv); |
||
134 | } |
||
135 | |||
136 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) |
||
137 | { |
||
138 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, |
||
139 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); |
||
140 | /* something from same cacheline, but !FORCEWAKE_MT */ |
||
141 | __raw_posting_read(dev_priv, ECOBUS); |
||
142 | gen6_gt_check_fifodbg(dev_priv); |
||
143 | } |
||
144 | |||
145 | static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) |
||
146 | { |
||
147 | int ret = 0; |
||
148 | |||
149 | if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { |
||
150 | int loop = 500; |
||
151 | u32 fifo = __raw_i915_read32(dev_priv, GT_FIFO_FREE_ENTRIES); |
||
152 | while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { |
||
153 | udelay(10); |
||
154 | fifo = __raw_i915_read32(dev_priv, GT_FIFO_FREE_ENTRIES); |
||
155 | } |
||
156 | if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) |
||
157 | ++ret; |
||
158 | dev_priv->uncore.fifo_count = fifo; |
||
159 | } |
||
160 | dev_priv->uncore.fifo_count--; |
||
161 | |||
162 | return ret; |
||
163 | } |
||
164 | |||
165 | static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) |
||
166 | { |
||
167 | __raw_i915_write32(dev_priv, FORCEWAKE_VLV, |
||
168 | _MASKED_BIT_DISABLE(0xffff)); |
||
169 | /* something from same cacheline, but !FORCEWAKE_VLV */ |
||
170 | __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV); |
||
171 | } |
||
172 | |||
173 | static void vlv_force_wake_get(struct drm_i915_private *dev_priv) |
||
174 | { |
||
175 | if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL) == 0, |
||
176 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
177 | DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); |
||
178 | |||
179 | __raw_i915_write32(dev_priv, FORCEWAKE_VLV, |
||
180 | _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); |
||
181 | __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, |
||
182 | _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); |
||
183 | |||
184 | if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK_VLV) & FORCEWAKE_KERNEL), |
||
185 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
186 | DRM_ERROR("Timed out waiting for GT to ack forcewake request.\n"); |
||
187 | |||
188 | if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK_MEDIA_VLV) & |
||
189 | FORCEWAKE_KERNEL), |
||
190 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
191 | DRM_ERROR("Timed out waiting for media to ack forcewake request.\n"); |
||
192 | |||
193 | /* WaRsForcewakeWaitTC0:vlv */ |
||
194 | __gen6_gt_wait_for_thread_c0(dev_priv); |
||
195 | } |
||
196 | |||
197 | static void vlv_force_wake_put(struct drm_i915_private *dev_priv) |
||
198 | { |
||
199 | __raw_i915_write32(dev_priv, FORCEWAKE_VLV, |
||
200 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); |
||
201 | __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, |
||
202 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); |
||
203 | /* The below doubles as a POSTING_READ */ |
||
204 | gen6_gt_check_fifodbg(dev_priv); |
||
205 | } |
||
206 | |||
207 | void intel_uncore_early_sanitize(struct drm_device *dev) |
||
208 | { |
||
209 | struct drm_i915_private *dev_priv = dev->dev_private; |
||
210 | |||
211 | if (HAS_FPGA_DBG_UNCLAIMED(dev)) |
||
212 | __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); |
||
213 | } |
||
214 | |||
215 | void intel_uncore_init(struct drm_device *dev) |
||
216 | { |
||
217 | struct drm_i915_private *dev_priv = dev->dev_private; |
||
218 | |||
219 | if (IS_VALLEYVIEW(dev)) { |
||
220 | dev_priv->uncore.funcs.force_wake_get = vlv_force_wake_get; |
||
221 | dev_priv->uncore.funcs.force_wake_put = vlv_force_wake_put; |
||
222 | } else if (IS_HASWELL(dev)) { |
||
223 | dev_priv->uncore.funcs.force_wake_get = __gen6_gt_force_wake_mt_get; |
||
224 | dev_priv->uncore.funcs.force_wake_put = __gen6_gt_force_wake_mt_put; |
||
225 | } else if (IS_IVYBRIDGE(dev)) { |
||
226 | u32 ecobus; |
||
227 | |||
228 | /* IVB configs may use multi-threaded forcewake */ |
||
229 | |||
230 | /* A small trick here - if the bios hasn't configured |
||
231 | * MT forcewake, and if the device is in RC6, then |
||
232 | * force_wake_mt_get will not wake the device and the |
||
233 | * ECOBUS read will return zero. Which will be |
||
234 | * (correctly) interpreted by the test below as MT |
||
235 | * forcewake being disabled. |
||
236 | */ |
||
237 | mutex_lock(&dev->struct_mutex); |
||
238 | __gen6_gt_force_wake_mt_get(dev_priv); |
||
239 | ecobus = __raw_i915_read32(dev_priv, ECOBUS); |
||
240 | __gen6_gt_force_wake_mt_put(dev_priv); |
||
241 | mutex_unlock(&dev->struct_mutex); |
||
242 | |||
243 | if (ecobus & FORCEWAKE_MT_ENABLE) { |
||
244 | dev_priv->uncore.funcs.force_wake_get = |
||
245 | __gen6_gt_force_wake_mt_get; |
||
246 | dev_priv->uncore.funcs.force_wake_put = |
||
247 | __gen6_gt_force_wake_mt_put; |
||
248 | } else { |
||
249 | DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n"); |
||
250 | DRM_INFO("when using vblank-synced partial screen updates.\n"); |
||
251 | dev_priv->uncore.funcs.force_wake_get = |
||
252 | __gen6_gt_force_wake_get; |
||
253 | dev_priv->uncore.funcs.force_wake_put = |
||
254 | __gen6_gt_force_wake_put; |
||
255 | } |
||
256 | } else if (IS_GEN6(dev)) { |
||
257 | dev_priv->uncore.funcs.force_wake_get = |
||
258 | __gen6_gt_force_wake_get; |
||
259 | dev_priv->uncore.funcs.force_wake_put = |
||
260 | __gen6_gt_force_wake_put; |
||
261 | } |
||