Rev 4560 | Rev 5354 | Go to most recent revision | Details | Compare with Previous | 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 | |||
5060 | serge | 43 | static void |
44 | assert_device_not_suspended(struct drm_i915_private *dev_priv) |
||
45 | { |
||
46 | WARN(HAS_RUNTIME_PM(dev_priv->dev) && dev_priv->pm.suspended, |
||
47 | "Device suspended\n"); |
||
48 | } |
||
4104 | Serge | 49 | |
50 | static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) |
||
51 | { |
||
52 | u32 gt_thread_status_mask; |
||
53 | |||
54 | if (IS_HASWELL(dev_priv->dev)) |
||
55 | gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK_HSW; |
||
56 | else |
||
57 | gt_thread_status_mask = GEN6_GT_THREAD_STATUS_CORE_MASK; |
||
58 | |||
59 | /* w/a for a sporadic read returning 0 by waiting for the GT |
||
60 | * thread to wake up. |
||
61 | */ |
||
62 | if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) & gt_thread_status_mask) == 0, 500)) |
||
63 | DRM_ERROR("GT thread status wait timed out\n"); |
||
64 | } |
||
65 | |||
66 | static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv) |
||
67 | { |
||
68 | __raw_i915_write32(dev_priv, FORCEWAKE, 0); |
||
69 | /* something from same cacheline, but !FORCEWAKE */ |
||
70 | __raw_posting_read(dev_priv, ECOBUS); |
||
71 | } |
||
72 | |||
4560 | Serge | 73 | static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, |
74 | int fw_engine) |
||
4104 | Serge | 75 | { |
76 | if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1) == 0, |
||
77 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
78 | DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); |
||
79 | |||
80 | __raw_i915_write32(dev_priv, FORCEWAKE, 1); |
||
81 | /* something from same cacheline, but !FORCEWAKE */ |
||
82 | __raw_posting_read(dev_priv, ECOBUS); |
||
83 | |||
84 | if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1), |
||
85 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
86 | DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); |
||
87 | |||
88 | /* WaRsForcewakeWaitTC0:snb */ |
||
89 | __gen6_gt_wait_for_thread_c0(dev_priv); |
||
90 | } |
||
91 | |||
5060 | serge | 92 | static void __gen7_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv) |
4104 | Serge | 93 | { |
94 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff)); |
||
95 | /* something from same cacheline, but !FORCEWAKE_MT */ |
||
96 | __raw_posting_read(dev_priv, ECOBUS); |
||
97 | } |
||
98 | |||
5060 | serge | 99 | static void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv, |
4560 | Serge | 100 | int fw_engine) |
4104 | Serge | 101 | { |
102 | u32 forcewake_ack; |
||
103 | |||
4560 | Serge | 104 | if (IS_HASWELL(dev_priv->dev) || IS_GEN8(dev_priv->dev)) |
4104 | Serge | 105 | forcewake_ack = FORCEWAKE_ACK_HSW; |
106 | else |
||
107 | forcewake_ack = FORCEWAKE_MT_ACK; |
||
108 | |||
109 | if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL) == 0, |
||
110 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
111 | DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n"); |
||
112 | |||
113 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, |
||
114 | _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); |
||
115 | /* something from same cacheline, but !FORCEWAKE_MT */ |
||
116 | __raw_posting_read(dev_priv, ECOBUS); |
||
117 | |||
118 | if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL), |
||
119 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
120 | DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); |
||
121 | |||
122 | /* WaRsForcewakeWaitTC0:ivb,hsw */ |
||
4560 | Serge | 123 | if (INTEL_INFO(dev_priv->dev)->gen < 8) |
4104 | Serge | 124 | __gen6_gt_wait_for_thread_c0(dev_priv); |
125 | } |
||
126 | |||
127 | static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) |
||
128 | { |
||
129 | u32 gtfifodbg; |
||
130 | |||
131 | gtfifodbg = __raw_i915_read32(dev_priv, GTFIFODBG); |
||
4560 | Serge | 132 | if (WARN(gtfifodbg, "GT wake FIFO error 0x%x\n", gtfifodbg)) |
133 | __raw_i915_write32(dev_priv, GTFIFODBG, gtfifodbg); |
||
4104 | Serge | 134 | } |
135 | |||
4560 | Serge | 136 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, |
137 | int fw_engine) |
||
4104 | Serge | 138 | { |
139 | __raw_i915_write32(dev_priv, FORCEWAKE, 0); |
||
140 | /* something from same cacheline, but !FORCEWAKE */ |
||
141 | __raw_posting_read(dev_priv, ECOBUS); |
||
142 | gen6_gt_check_fifodbg(dev_priv); |
||
143 | } |
||
144 | |||
5060 | serge | 145 | static void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv, |
4560 | Serge | 146 | int fw_engine) |
4104 | Serge | 147 | { |
148 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, |
||
149 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); |
||
150 | /* something from same cacheline, but !FORCEWAKE_MT */ |
||
151 | __raw_posting_read(dev_priv, ECOBUS); |
||
5060 | serge | 152 | |
153 | if (IS_GEN7(dev_priv->dev)) |
||
4104 | Serge | 154 | gen6_gt_check_fifodbg(dev_priv); |
155 | } |
||
156 | |||
157 | static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) |
||
158 | { |
||
159 | int ret = 0; |
||
160 | |||
4560 | Serge | 161 | /* On VLV, FIFO will be shared by both SW and HW. |
162 | * So, we need to read the FREE_ENTRIES everytime */ |
||
163 | if (IS_VALLEYVIEW(dev_priv->dev)) |
||
164 | dev_priv->uncore.fifo_count = |
||
165 | __raw_i915_read32(dev_priv, GTFIFOCTL) & |
||
166 | GT_FIFO_FREE_ENTRIES_MASK; |
||
167 | |||
4104 | Serge | 168 | if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { |
169 | int loop = 500; |
||
4560 | Serge | 170 | u32 fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK; |
4104 | Serge | 171 | while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { |
172 | udelay(10); |
||
4560 | Serge | 173 | fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK; |
4104 | Serge | 174 | } |
175 | if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) |
||
176 | ++ret; |
||
177 | dev_priv->uncore.fifo_count = fifo; |
||
178 | } |
||
179 | dev_priv->uncore.fifo_count--; |
||
180 | |||
181 | return ret; |
||
182 | } |
||
183 | |||
184 | static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) |
||
185 | { |
||
186 | __raw_i915_write32(dev_priv, FORCEWAKE_VLV, |
||
187 | _MASKED_BIT_DISABLE(0xffff)); |
||
5060 | serge | 188 | __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, |
189 | _MASKED_BIT_DISABLE(0xffff)); |
||
4104 | Serge | 190 | /* something from same cacheline, but !FORCEWAKE_VLV */ |
191 | __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV); |
||
192 | } |
||
193 | |||
4560 | Serge | 194 | static void __vlv_force_wake_get(struct drm_i915_private *dev_priv, |
195 | int fw_engine) |
||
4104 | Serge | 196 | { |
4560 | Serge | 197 | /* Check for Render Engine */ |
198 | if (FORCEWAKE_RENDER & fw_engine) { |
||
199 | if (wait_for_atomic((__raw_i915_read32(dev_priv, |
||
200 | FORCEWAKE_ACK_VLV) & |
||
201 | FORCEWAKE_KERNEL) == 0, |
||
4104 | Serge | 202 | FORCEWAKE_ACK_TIMEOUT_MS)) |
4560 | Serge | 203 | DRM_ERROR("Timed out: Render forcewake old ack to clear.\n"); |
4104 | Serge | 204 | |
205 | __raw_i915_write32(dev_priv, FORCEWAKE_VLV, |
||
206 | _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); |
||
4560 | Serge | 207 | |
208 | if (wait_for_atomic((__raw_i915_read32(dev_priv, |
||
209 | FORCEWAKE_ACK_VLV) & |
||
210 | FORCEWAKE_KERNEL), |
||
211 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
212 | DRM_ERROR("Timed out: waiting for Render to ack.\n"); |
||
213 | } |
||
214 | |||
215 | /* Check for Media Engine */ |
||
216 | if (FORCEWAKE_MEDIA & fw_engine) { |
||
217 | if (wait_for_atomic((__raw_i915_read32(dev_priv, |
||
218 | FORCEWAKE_ACK_MEDIA_VLV) & |
||
219 | FORCEWAKE_KERNEL) == 0, |
||
220 | FORCEWAKE_ACK_TIMEOUT_MS)) |
||
221 | DRM_ERROR("Timed out: Media forcewake old ack to clear.\n"); |
||
222 | |||
4104 | Serge | 223 | __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, |
224 | _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL)); |
||
225 | |||
4560 | Serge | 226 | if (wait_for_atomic((__raw_i915_read32(dev_priv, |
227 | FORCEWAKE_ACK_MEDIA_VLV) & |
||
4104 | Serge |