Rev 5354 | Rev 6660 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5354 | Rev 6084 | ||
---|---|---|---|
Line 26... | Line 26... | ||
26 | */ |
26 | */ |
Line 27... | Line 27... | ||
27 | 27 | ||
28 | //#include |
28 | //#include |
29 | #include "i915_drv.h" |
29 | #include "i915_drv.h" |
30 | #include "intel_drv.h" |
- | |
31 | #include |
30 | #include "intel_drv.h" |
32 | //#include "../../../platform/x86/intel_ips.h" |
31 | //#include "../../../platform/x86/intel_ips.h" |
Line 33... | Line -... | ||
33 | #include |
- | |
Line 34... | Line 32... | ||
34 | 32 | #include |
|
Line 35... | Line 33... | ||
35 | #include |
33 | |
Line 36... | Line -... | ||
36 | - | ||
37 | #define FORCEWAKE_ACK_TIMEOUT_MS 2 |
- | |
38 | - | ||
39 | void getrawmonotonic(struct timespec *ts); |
- | |
40 | - | ||
41 | union ktime { |
- | |
42 | s64 tv64; |
- | |
43 | }; |
- | |
44 | - | ||
45 | typedef union ktime ktime_t; /* Kill this */ |
- | |
46 | - | ||
47 | #define ktime_to_ns(kt) ((kt).tv64) |
- | |
48 | 34 | ||
49 | static inline u64 ktime_get_raw_ns(void) |
35 | #define FORCEWAKE_ACK_TIMEOUT_MS 2 |
50 | { |
36 | |
51 | return 0; //ktime_to_ns(ktime_get_raw()); |
37 | void getrawmonotonic(struct timespec *ts); |
52 | } |
38 | |
Line 69... | Line 55... | ||
69 | */ |
55 | */ |
70 | #define INTEL_RC6_ENABLE (1<<0) |
56 | #define INTEL_RC6_ENABLE (1<<0) |
71 | #define INTEL_RC6p_ENABLE (1<<1) |
57 | #define INTEL_RC6p_ENABLE (1<<1) |
72 | #define INTEL_RC6pp_ENABLE (1<<2) |
58 | #define INTEL_RC6pp_ENABLE (1<<2) |
Line 73... | Line -... | ||
73 | - | ||
74 | /* FBC, or Frame Buffer Compression, is a technique employed to compress the |
- | |
75 | * framebuffer contents in-memory, aiming at reducing the required bandwidth |
- | |
76 | * during in-memory transfers and, therefore, reduce the power packet. |
- | |
77 | * |
- | |
78 | * The benefits of FBC are mostly visible with solid backgrounds and |
- | |
79 | * variation-less patterns. |
- | |
80 | * |
- | |
81 | * FBC-related functionality can be enabled by the means of the |
- | |
82 | * i915.i915_enable_fbc parameter |
- | |
83 | */ |
- | |
84 | 59 | ||
85 | static void gen9_init_clock_gating(struct drm_device *dev) |
60 | static void bxt_init_clock_gating(struct drm_device *dev) |
86 | { |
61 | { |
Line 87... | Line -... | ||
87 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
88 | 62 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
89 | /* |
- | |
90 | * WaDisableSDEUnitClockGating:skl |
- | |
91 | * This seems to be a pre-production w/a. |
63 | |
92 | */ |
64 | /* WaDisableSDEUnitClockGating:bxt */ |
Line 93... | Line 65... | ||
93 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
65 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
94 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); |
66 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); |
95 | 67 | ||
96 | /* |
68 | /* |
97 | * WaDisableDgMirrorFixInHalfSliceChicken5:skl |
69 | * FIXME: |
98 | * This is a pre-production w/a. |
- | |
99 | */ |
70 | * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only. |
100 | I915_WRITE(GEN9_HALF_SLICE_CHICKEN5, |
- | |
101 | I915_READ(GEN9_HALF_SLICE_CHICKEN5) & |
- | |
102 | ~GEN9_DG_MIRROR_FIX_ENABLE); |
- | |
103 | - | ||
104 | /* Wa4x4STCOptimizationDisable:skl */ |
- | |
105 | I915_WRITE(CACHE_MODE_1, |
- | |
106 | _MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE)); |
- | |
107 | } |
- | |
108 | - | ||
109 | static void i8xx_disable_fbc(struct drm_device *dev) |
- | |
110 | { |
- | |
111 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
112 | u32 fbc_ctl; |
- | |
113 | - | ||
114 | dev_priv->fbc.enabled = false; |
- | |
115 | - | ||
116 | /* Disable compression */ |
- | |
117 | fbc_ctl = I915_READ(FBC_CONTROL); |
- | |
118 | if ((fbc_ctl & FBC_CTL_EN) == 0) |
- | |
119 | return; |
- | |
120 | - | ||
121 | fbc_ctl &= ~FBC_CTL_EN; |
- | |
122 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
- | |
123 | - | ||
124 | /* Wait for compressing bit to clear */ |
- | |
125 | if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) { |
- | |
126 | DRM_DEBUG_KMS("FBC idle timed out\n"); |
- | |
127 | return; |
- | |
128 | } |
- | |
129 | - | ||
130 | DRM_DEBUG_KMS("disabled FBC\n"); |
- | |
131 | } |
- | |
132 | - | ||
133 | static void i8xx_enable_fbc(struct drm_crtc *crtc) |
- | |
134 | { |
- | |
135 | struct drm_device *dev = crtc->dev; |
- | |
136 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
137 | struct drm_framebuffer *fb = crtc->primary->fb; |
- | |
138 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
- | |
139 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
140 | int cfb_pitch; |
- | |
141 | int i; |
- | |
142 | u32 fbc_ctl; |
- | |
143 | - | ||
144 | dev_priv->fbc.enabled = true; |
- | |
145 | - | ||
146 | cfb_pitch = dev_priv->fbc.size / FBC_LL_SIZE; |
- | |
147 | if (fb->pitches[0] < cfb_pitch) |
- | |
148 | cfb_pitch = fb->pitches[0]; |
- | |
149 | - | ||
150 | /* FBC_CTL wants 32B or 64B units */ |
- | |
151 | if (IS_GEN2(dev)) |
- | |
152 | cfb_pitch = (cfb_pitch / 32) - 1; |
- | |
153 | else |
- | |
154 | cfb_pitch = (cfb_pitch / 64) - 1; |
- | |
155 | - | ||
156 | /* Clear old tags */ |
- | |
157 | for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++) |
- | |
158 | I915_WRITE(FBC_TAG + (i * 4), 0); |
- | |
159 | - | ||
160 | if (IS_GEN4(dev)) { |
- | |
161 | u32 fbc_ctl2; |
- | |
162 | - | ||
163 | /* Set it up... */ |
- | |
164 | fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE; |
- | |
165 | fbc_ctl2 |= FBC_CTL_PLANE(intel_crtc->plane); |
- | |
166 | I915_WRITE(FBC_CONTROL2, fbc_ctl2); |
- | |
167 | I915_WRITE(FBC_FENCE_OFF, crtc->y); |
- | |
168 | } |
- | |
169 | - | ||
170 | /* enable it... */ |
- | |
171 | fbc_ctl = I915_READ(FBC_CONTROL); |
- | |
172 | fbc_ctl &= 0x3fff << FBC_CTL_INTERVAL_SHIFT; |
- | |
173 | fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC; |
- | |
174 | if (IS_I945GM(dev)) |
- | |
175 | fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ |
- | |
176 | fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; |
- | |
177 | fbc_ctl |= obj->fence_reg; |
- | |
178 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
- | |
179 | - | ||
180 | DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %c\n", |
- | |
181 | cfb_pitch, crtc->y, plane_name(intel_crtc->plane)); |
- | |
182 | } |
- | |
183 | - | ||
184 | static bool i8xx_fbc_enabled(struct drm_device *dev) |
- | |
185 | { |
- | |
186 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
187 | - | ||
188 | return I915_READ(FBC_CONTROL) & FBC_CTL_EN; |
- | |
189 | } |
- | |
190 | - | ||
191 | static void g4x_enable_fbc(struct drm_crtc *crtc) |
- | |
192 | { |
- | |
193 | struct drm_device *dev = crtc->dev; |
- | |
194 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
195 | struct drm_framebuffer *fb = crtc->primary->fb; |
- | |
196 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
- | |
197 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
198 | u32 dpfc_ctl; |
- | |
199 | - | ||
200 | dev_priv->fbc.enabled = true; |
- | |
201 | - | ||
202 | dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane) | DPFC_SR_EN; |
- | |
203 | if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) |
- | |
204 | dpfc_ctl |= DPFC_CTL_LIMIT_2X; |
- | |
205 | else |
- | |
206 | dpfc_ctl |= DPFC_CTL_LIMIT_1X; |
- | |
207 | dpfc_ctl |= DPFC_CTL_FENCE_EN | obj->fence_reg; |
- | |
208 | - | ||
209 | I915_WRITE(DPFC_FENCE_YOFF, crtc->y); |
- | |
210 | - | ||
211 | /* enable it... */ |
- | |
212 | I915_WRITE(DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); |
- | |
213 | - | ||
214 | DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane)); |
- | |
215 | } |
- | |
216 | - | ||
217 | static void g4x_disable_fbc(struct drm_device *dev) |
- | |
218 | { |
- | |
219 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
220 | u32 dpfc_ctl; |
- | |
221 | - | ||
222 | dev_priv->fbc.enabled = false; |
- | |
223 | - | ||
224 | /* Disable compression */ |
- | |
225 | dpfc_ctl = I915_READ(DPFC_CONTROL); |
- | |
226 | if (dpfc_ctl & DPFC_CTL_EN) { |
- | |
227 | dpfc_ctl &= ~DPFC_CTL_EN; |
- | |
228 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); |
- | |
229 | - | ||
230 | DRM_DEBUG_KMS("disabled FBC\n"); |
- | |
231 | } |
- | |
232 | } |
- | |
233 | - | ||
234 | static bool g4x_fbc_enabled(struct drm_device *dev) |
- | |
235 | { |
- | |
236 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
237 | - | ||
238 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; |
- | |
239 | } |
- | |
240 | - | ||
241 | static void sandybridge_blit_fbc_update(struct drm_device *dev) |
- | |
242 | { |
- | |
243 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
244 | u32 blt_ecoskpd; |
- | |
245 | - | ||
246 | /* Make sure blitter notifies FBC of writes */ |
- | |
247 | - | ||
248 | /* Blitter is part of Media powerwell on VLV. No impact of |
- | |
249 | * his param in other platforms for now */ |
- | |
250 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_MEDIA); |
- | |
251 | - | ||
252 | blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD); |
- | |
253 | blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY << |
- | |
254 | GEN6_BLITTER_LOCK_SHIFT; |
- | |
255 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); |
- | |
256 | blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY; |
- | |
257 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); |
- | |
258 | blt_ecoskpd &= ~(GEN6_BLITTER_FBC_NOTIFY << |
- | |
259 | GEN6_BLITTER_LOCK_SHIFT); |
- | |
260 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); |
- | |
261 | POSTING_READ(GEN6_BLITTER_ECOSKPD); |
- | |
262 | - | ||
263 | gen6_gt_force_wake_put(dev_priv, FORCEWAKE_MEDIA); |
- | |
264 | } |
- | |
265 | - | ||
266 | static void ironlake_enable_fbc(struct drm_crtc *crtc) |
- | |
267 | { |
- | |
268 | struct drm_device *dev = crtc->dev; |
- | |
269 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
270 | struct drm_framebuffer *fb = crtc->primary->fb; |
- | |
271 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
- | |
272 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
273 | u32 dpfc_ctl; |
- | |
274 | - | ||
275 | dev_priv->fbc.enabled = true; |
- | |
276 | - | ||
277 | dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane); |
- | |
278 | if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) |
- | |
279 | dev_priv->fbc.threshold++; |
- | |
280 | - | ||
281 | switch (dev_priv->fbc.threshold) { |
- | |
282 | case 4: |
- | |
283 | case 3: |
- | |
284 | dpfc_ctl |= DPFC_CTL_LIMIT_4X; |
- | |
285 | break; |
- | |
286 | case 2: |
- | |
287 | dpfc_ctl |= DPFC_CTL_LIMIT_2X; |
- | |
288 | break; |
- | |
289 | case 1: |
- | |
290 | dpfc_ctl |= DPFC_CTL_LIMIT_1X; |
- | |
291 | break; |
- | |
292 | } |
- | |
293 | dpfc_ctl |= DPFC_CTL_FENCE_EN; |
- | |
294 | if (IS_GEN5(dev)) |
- | |
295 | dpfc_ctl |= obj->fence_reg; |
- | |
296 | - | ||
297 | I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); |
- | |
298 | I915_WRITE(ILK_FBC_RT_BASE, i915_gem_obj_ggtt_offset(obj) | ILK_FBC_RT_VALID); |
- | |
299 | /* enable it... */ |
- | |
300 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); |
- | |
301 | - | ||
302 | if (IS_GEN6(dev)) { |
- | |
303 | I915_WRITE(SNB_DPFC_CTL_SA, |
- | |
304 | SNB_CPU_FENCE_ENABLE | obj->fence_reg); |
- | |
305 | I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); |
- | |
306 | sandybridge_blit_fbc_update(dev); |
- | |
307 | } |
- | |
308 | - | ||
309 | DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane)); |
- | |
310 | } |
- | |
311 | - | ||
312 | static void ironlake_disable_fbc(struct drm_device *dev) |
- | |
313 | { |
- | |
314 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
315 | u32 dpfc_ctl; |
- | |
316 | - | ||
317 | dev_priv->fbc.enabled = false; |
- | |
318 | - | ||
319 | /* Disable compression */ |
- | |
320 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); |
- | |
321 | if (dpfc_ctl & DPFC_CTL_EN) { |
- | |
322 | dpfc_ctl &= ~DPFC_CTL_EN; |
- | |
323 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); |
- | |
324 | - | ||
325 | DRM_DEBUG_KMS("disabled FBC\n"); |
- | |
326 | } |
- | |
327 | } |
- | |
328 | - | ||
329 | static bool ironlake_fbc_enabled(struct drm_device *dev) |
- | |
330 | { |
- | |
331 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
332 | - | ||
333 | return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; |
- | |
334 | } |
- | |
335 | - | ||
336 | static void gen7_enable_fbc(struct drm_crtc *crtc) |
- | |
337 | { |
- | |
338 | struct drm_device *dev = crtc->dev; |
- | |
339 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
340 | struct drm_framebuffer *fb = crtc->primary->fb; |
- | |
341 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
- | |
342 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
343 | u32 dpfc_ctl; |
- | |
344 | - | ||
345 | dev_priv->fbc.enabled = true; |
- | |
346 | - | ||
347 | dpfc_ctl = IVB_DPFC_CTL_PLANE(intel_crtc->plane); |
- | |
348 | if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) |
- | |
349 | dev_priv->fbc.threshold++; |
- | |
350 | - | ||
351 | switch (dev_priv->fbc.threshold) { |
- | |
352 | case 4: |
- | |
353 | case 3: |
- | |
354 | dpfc_ctl |= DPFC_CTL_LIMIT_4X; |
- | |
355 | break; |
- | |
356 | case 2: |
- | |
357 | dpfc_ctl |= DPFC_CTL_LIMIT_2X; |
- | |
358 | break; |
- | |
359 | case 1: |
- | |
360 | dpfc_ctl |= DPFC_CTL_LIMIT_1X; |
- | |
361 | break; |
- | |
362 | } |
- | |
363 | - | ||
364 | dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN; |
- | |
365 | - | ||
366 | if (dev_priv->fbc.false_color) |
- | |
367 | dpfc_ctl |= FBC_CTL_FALSE_COLOR; |
- | |
368 | - | ||
369 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); |
- | |
370 | - | ||
371 | if (IS_IVYBRIDGE(dev)) { |
- | |
372 | /* WaFbcAsynchFlipDisableFbcQueue:ivb */ |
- | |
373 | I915_WRITE(ILK_DISPLAY_CHICKEN1, |
- | |
374 | I915_READ(ILK_DISPLAY_CHICKEN1) | |
- | |
375 | ILK_FBCQ_DIS); |
- | |
376 | } else { |
- | |
377 | /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ |
- | |
378 | I915_WRITE(CHICKEN_PIPESL_1(intel_crtc->pipe), |
- | |
379 | I915_READ(CHICKEN_PIPESL_1(intel_crtc->pipe)) | |
- | |
380 | HSW_FBCQ_DIS); |
- | |
381 | } |
- | |
382 | - | ||
383 | I915_WRITE(SNB_DPFC_CTL_SA, |
- | |
384 | SNB_CPU_FENCE_ENABLE | obj->fence_reg); |
- | |
385 | I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); |
- | |
386 | - | ||
387 | sandybridge_blit_fbc_update(dev); |
- | |
388 | - | ||
389 | DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane)); |
- | |
390 | } |
- | |
391 | - | ||
392 | bool intel_fbc_enabled(struct drm_device *dev) |
- | |
393 | { |
- | |
394 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
395 | - | ||
396 | return dev_priv->fbc.enabled; |
- | |
397 | } |
- | |
398 | - | ||
399 | void bdw_fbc_sw_flush(struct drm_device *dev, u32 value) |
- | |
400 | { |
- | |
401 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
402 | - | ||
403 | if (!IS_GEN8(dev)) |
- | |
404 | return; |
- | |
405 | - | ||
406 | if (!intel_fbc_enabled(dev)) |
- | |
407 | return; |
- | |
408 | - | ||
409 | I915_WRITE(MSG_FBC_REND_STATE, value); |
- | |
410 | } |
- | |
411 | - | ||
412 | static void intel_fbc_work_fn(struct work_struct *__work) |
- | |
413 | { |
- | |
414 | struct intel_fbc_work *work = |
- | |
415 | container_of(to_delayed_work(__work), |
- | |
416 | struct intel_fbc_work, work); |
- | |
417 | struct drm_device *dev = work->crtc->dev; |
- | |
418 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
419 | - | ||
420 | mutex_lock(&dev->struct_mutex); |
- | |
421 | if (work == dev_priv->fbc.fbc_work) { |
- | |
422 | /* Double check that we haven't switched fb without cancelling |
- | |
423 | * the prior work. |
- | |
424 | */ |
- | |
425 | if (work->crtc->primary->fb == work->fb) { |
- | |
426 | dev_priv->display.enable_fbc(work->crtc); |
- | |
427 | - | ||
428 | dev_priv->fbc.plane = to_intel_crtc(work->crtc)->plane; |
- | |
429 | dev_priv->fbc.fb_id = work->crtc->primary->fb->base.id; |
- | |
430 | dev_priv->fbc.y = work->crtc->y; |
- | |
431 | } |
- | |
432 | - | ||
433 | dev_priv->fbc.fbc_work = NULL; |
- | |
434 | } |
- | |
435 | mutex_unlock(&dev->struct_mutex); |
- | |
436 | - | ||
437 | kfree(work); |
- | |
438 | } |
- | |
439 | - | ||
440 | static void intel_cancel_fbc_work(struct drm_i915_private *dev_priv) |
- | |
441 | { |
- | |
442 | if (dev_priv->fbc.fbc_work == NULL) |
- | |
443 | return; |
- | |
444 | - | ||
445 | DRM_DEBUG_KMS("cancelling pending FBC enable\n"); |
- | |
446 | - | ||
447 | /* Synchronisation is provided by struct_mutex and checking of |
- | |
448 | * dev_priv->fbc.fbc_work, so we can perform the cancellation |
- | |
449 | * entirely asynchronously. |
- | |
450 | */ |
- | |
451 | if (cancel_delayed_work(&dev_priv->fbc.fbc_work->work)) |
- | |
452 | /* tasklet was killed before being run, clean up */ |
- | |
453 | kfree(dev_priv->fbc.fbc_work); |
- | |
454 | - | ||
455 | /* Mark the work as no longer wanted so that if it does |
- | |
456 | * wake-up (because the work was already running and waiting |
- | |
457 | * for our mutex), it will discover that is no longer |
- | |
458 | * necessary to run. |
- | |
459 | */ |
- | |
460 | dev_priv->fbc.fbc_work = NULL; |
- | |
461 | } |
- | |
462 | - | ||
463 | static void intel_enable_fbc(struct drm_crtc *crtc) |
- | |
464 | { |
- | |
465 | struct intel_fbc_work *work; |
- | |
466 | struct drm_device *dev = crtc->dev; |
- | |
467 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
468 | - | ||
469 | if (!dev_priv->display.enable_fbc) |
- | |
470 | return; |
- | |
471 | - | ||
472 | intel_cancel_fbc_work(dev_priv); |
- | |
473 | - | ||
474 | work = kzalloc(sizeof(*work), GFP_KERNEL); |
- | |
475 | if (work == NULL) { |
- | |
476 | DRM_ERROR("Failed to allocate FBC work structure\n"); |
- | |
477 | dev_priv->display.enable_fbc(crtc); |
- | |
478 | return; |
- | |
479 | } |
- | |
480 | - | ||
481 | work->crtc = crtc; |
- | |
482 | work->fb = crtc->primary->fb; |
- | |
483 | INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn); |
- | |
484 | - | ||
485 | dev_priv->fbc.fbc_work = work; |
- | |
486 | - | ||
487 | /* Delay the actual enabling to let pageflipping cease and the |
- | |
488 | * display to settle before starting the compression. Note that |
- | |
489 | * this delay also serves a second purpose: it allows for a |
- | |
490 | * vblank to pass after disabling the FBC before we attempt |
- | |
491 | * to modify the control registers. |
- | |
492 | * |
- | |
493 | * A more complicated solution would involve tracking vblanks |
- | |
494 | * following the termination of the page-flipping sequence |
- | |
495 | * and indeed performing the enable as a co-routine and not |
- | |
496 | * waiting synchronously upon the vblank. |
- | |
497 | * |
- | |
498 | * WaFbcWaitForVBlankBeforeEnable:ilk,snb |
- | |
499 | */ |
- | |
500 | schedule_delayed_work(&work->work, msecs_to_jiffies(50)); |
- | |
501 | } |
- | |
502 | - | ||
503 | void intel_disable_fbc(struct drm_device *dev) |
- | |
504 | { |
- | |
505 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
506 | - | ||
507 | intel_cancel_fbc_work(dev_priv); |
- | |
508 | - | ||
509 | if (!dev_priv->display.disable_fbc) |
- | |
510 | return; |
- | |
511 | - | ||
512 | dev_priv->display.disable_fbc(dev); |
- | |
513 | dev_priv->fbc.plane = -1; |
- | |
514 | } |
- | |
515 | - | ||
516 | static bool set_no_fbc_reason(struct drm_i915_private *dev_priv, |
- | |
517 | enum no_fbc_reason reason) |
- | |
518 | { |
- | |
519 | if (dev_priv->fbc.no_fbc_reason == reason) |
- | |
520 | return false; |
- | |
521 | - | ||
522 | dev_priv->fbc.no_fbc_reason = reason; |
- | |
523 | return true; |
- | |
524 | } |
- | |
525 | - | ||
526 | /** |
- | |
527 | * intel_update_fbc - enable/disable FBC as needed |
- | |
528 | * @dev: the drm_device |
- | |
529 | * |
- | |
530 | * Set up the framebuffer compression hardware at mode set time. We |
- | |
531 | * enable it if possible: |
- | |
532 | * - plane A only (on pre-965) |
- | |
533 | * - no pixel mulitply/line duplication |
- | |
534 | * - no alpha buffer discard |
- | |
535 | * - no dual wide |
- | |
536 | * - framebuffer <= max_hdisplay in width, max_vdisplay in height |
- | |
537 | * |
- | |
538 | * We can't assume that any compression will take place (worst case), |
- | |
539 | * so the compressed buffer has to be the same size as the uncompressed |
- | |
540 | * one. It also must reside (along with the line length buffer) in |
- | |
541 | * stolen memory. |
- | |
542 | * |
- | |
543 | * We need to enable/disable FBC on a global basis. |
- | |
544 | */ |
- | |
545 | void intel_update_fbc(struct drm_device *dev) |
- | |
546 | { |
- | |
547 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
548 | struct drm_crtc *crtc = NULL, *tmp_crtc; |
- | |
549 | struct intel_crtc *intel_crtc; |
- | |
550 | struct drm_framebuffer *fb; |
- | |
551 | struct drm_i915_gem_object *obj; |
- | |
552 | const struct drm_display_mode *adjusted_mode; |
- | |
553 | unsigned int max_width, max_height; |
- | |
554 | - | ||
555 | if (!HAS_FBC(dev)) { |
- | |
556 | set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED); |
- | |
557 | return; |
- | |
558 | } |
- | |
559 | - | ||
560 | if (!i915.powersave) { |
- | |
561 | if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM)) |
- | |
562 | DRM_DEBUG_KMS("fbc disabled per module param\n"); |
- | |
563 | return; |
- | |
564 | } |
- | |
565 | - | ||
566 | /* |
- | |
567 | * If FBC is already on, we just have to verify that we can |
- | |
568 | * keep it that way... |
- | |
569 | * Need to disable if: |
- | |
570 | * - more than one pipe is active |
- | |
571 | * - changing FBC params (stride, fence, mode) |
- | |
572 | * - new fb is too large to fit in compressed buffer |
- | |
573 | * - going to an unsupported config (interlace, pixel multiply, etc.) |
- | |
574 | */ |
- | |
575 | for_each_crtc(dev, tmp_crtc) { |
- | |
576 | if (intel_crtc_active(tmp_crtc) && |
- | |
577 | to_intel_crtc(tmp_crtc)->primary_enabled) { |
- | |
578 | if (crtc) { |
- | |
579 | if (set_no_fbc_reason(dev_priv, FBC_MULTIPLE_PIPES)) |
- | |
580 | DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); |
- | |
581 | goto out_disable; |
- | |
582 | } |
- | |
583 | crtc = tmp_crtc; |
- | |
584 | } |
- | |
585 | } |
- | |
586 | - | ||
587 | if (!crtc || crtc->primary->fb == NULL) { |
- | |
588 | if (set_no_fbc_reason(dev_priv, FBC_NO_OUTPUT)) |
- | |
589 | DRM_DEBUG_KMS("no output, disabling\n"); |
- | |
590 | goto out_disable; |
- | |
591 | } |
- | |
592 | - | ||
593 | intel_crtc = to_intel_crtc(crtc); |
- | |
594 | fb = crtc->primary->fb; |
- | |
595 | obj = intel_fb_obj(fb); |
- | |
596 | adjusted_mode = &intel_crtc->config.adjusted_mode; |
- | |
597 | - | ||
598 | if (i915.enable_fbc < 0) { |
- | |
599 | if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT)) |
- | |
600 | DRM_DEBUG_KMS("disabled per chip default\n"); |
- | |
601 | goto out_disable; |
- | |
602 | } |
- | |
603 | if (!i915.enable_fbc) { |
- | |
604 | if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM)) |
- | |
605 | DRM_DEBUG_KMS("fbc disabled per module param\n"); |
- | |
606 | goto out_disable; |
- | |
607 | } |
- | |
608 | if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) || |
- | |
609 | (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) { |
- | |
610 | if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE)) |
- | |
611 | DRM_DEBUG_KMS("mode incompatible with compression, " |
- | |
612 | "disabling\n"); |
- | |
613 | goto out_disable; |
- | |
614 | } |
- | |
615 | - | ||
616 | if (INTEL_INFO(dev)->gen >= 8 || IS_HASWELL(dev)) { |
- | |
617 | max_width = 4096; |
- | |
618 | max_height = 4096; |
- | |
619 | } else if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { |
- | |
620 | max_width = 4096; |
- | |
621 | max_height = 2048; |
- | |
622 | } else { |
- | |
623 | max_width = 2048; |
- | |
624 | max_height = 1536; |
- | |
625 | } |
- | |
626 | if (intel_crtc->config.pipe_src_w > max_width || |
- | |
627 | intel_crtc->config.pipe_src_h > max_height) { |
- | |
628 | if (set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE)) |
- | |
629 | DRM_DEBUG_KMS("mode too large for compression, disabling\n"); |
- | |
630 | goto out_disable; |
- | |
631 | } |
- | |
632 | if ((INTEL_INFO(dev)->gen < 4 || HAS_DDI(dev)) && |
- | |
633 | intel_crtc->plane != PLANE_A) { |
- | |
634 | if (set_no_fbc_reason(dev_priv, FBC_BAD_PLANE)) |
- | |
635 | DRM_DEBUG_KMS("plane not A, disabling compression\n"); |
- | |
636 | goto out_disable; |
- | |
637 | } |
- | |
638 | - | ||
639 | /* The use of a CPU fence is mandatory in order to detect writes |
- | |
640 | * by the CPU to the scanout and trigger updates to the FBC. |
- | |
641 | */ |
- | |
642 | if (obj->tiling_mode != I915_TILING_X || |
- | |
643 | obj->fence_reg == I915_FENCE_REG_NONE) { |
- | |
644 | if (set_no_fbc_reason(dev_priv, FBC_NOT_TILED)) |
- | |
645 | DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n"); |
- | |
646 | goto out_disable; |
- | |
647 | } |
- | |
648 | if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) && |
- | |
649 | to_intel_plane(crtc->primary)->rotation != BIT(DRM_ROTATE_0)) { |
- | |
650 | if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE)) |
- | |
651 | DRM_DEBUG_KMS("Rotation unsupported, disabling\n"); |
- | |
652 | goto out_disable; |
- | |
653 | } |
- | |
654 | - | ||
655 | /* If the kernel debugger is active, always disable compression */ |
- | |
656 | if (in_dbg_master()) |
- | |
657 | goto out_disable; |
- | |
658 | - | ||
659 | if (i915_gem_stolen_setup_compression(dev, obj->base.size, |
- | |
660 | drm_format_plane_cpp(fb->pixel_format, 0))) { |
- | |
661 | if (set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL)) |
- | |
662 | DRM_DEBUG_KMS("framebuffer too large, disabling compression\n"); |
- | |
663 | goto out_disable; |
- | |
664 | } |
- | |
665 | - | ||
666 | /* If the scanout has not changed, don't modify the FBC settings. |
- | |
667 | * Note that we make the fundamental assumption that the fb->obj |
- | |
668 | * cannot be unpinned (and have its GTT offset and fence revoked) |
- | |
669 | * without first being decoupled from the scanout and FBC disabled. |
- | |
670 | */ |
- | |
671 | if (dev_priv->fbc.plane == intel_crtc->plane && |
- | |
672 | dev_priv->fbc.fb_id == fb->base.id && |
- | |
673 | dev_priv->fbc.y == crtc->y) |
- | |
674 | return; |
- | |
675 | - | ||
676 | if (intel_fbc_enabled(dev)) { |
- | |
677 | /* We update FBC along two paths, after changing fb/crtc |
- | |
678 | * configuration (modeswitching) and after page-flipping |
- | |
679 | * finishes. For the latter, we know that not only did |
- | |
680 | * we disable the FBC at the start of the page-flip |
- | |
681 | * sequence, but also more than one vblank has passed. |
- | |
682 | * |
- | |
683 | * For the former case of modeswitching, it is possible |
- | |
684 | * to switch between two FBC valid configurations |
- | |
685 | * instantaneously so we do need to disable the FBC |
- | |
686 | * before we can modify its control registers. We also |
- | |
687 | * have to wait for the next vblank for that to take |
- | |
688 | * effect. However, since we delay enabling FBC we can |
- | |
689 | * assume that a vblank has passed since disabling and |
- | |
690 | * that we can safely alter the registers in the deferred |
- | |
691 | * callback. |
- | |
692 | * |
- | |
693 | * In the scenario that we go from a valid to invalid |
- | |
694 | * and then back to valid FBC configuration we have |
- | |
695 | * no strict enforcement that a vblank occurred since |
- | |
696 | * disabling the FBC. However, along all current pipe |
- | |
697 | * disabling paths we do need to wait for a vblank at |
- | |
698 | * some point. And we wait before enabling FBC anyway. |
- | |
699 | */ |
- | |
700 | DRM_DEBUG_KMS("disabling active FBC for update\n"); |
- | |
701 | intel_disable_fbc(dev); |
- | |
702 | } |
- | |
703 | - | ||
704 | intel_enable_fbc(crtc); |
- | |
705 | dev_priv->fbc.no_fbc_reason = FBC_OK; |
- | |
706 | return; |
- | |
707 | - | ||
708 | out_disable: |
- | |
709 | /* Multiple disables should be harmless */ |
- | |
710 | if (intel_fbc_enabled(dev)) { |
- | |
711 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); |
- | |
712 | intel_disable_fbc(dev); |
71 | */ |
Line 713... | Line 72... | ||
713 | } |
72 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
714 | i915_gem_stolen_cleanup_compression(dev); |
73 | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); |
715 | } |
74 | } |
Line 881... | Line 240... | ||
881 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
240 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
Line 882... | Line 241... | ||
882 | 241 | ||
883 | return NULL; |
242 | return NULL; |
Line -... | Line 243... | ||
- | 243 | } |
|
- | 244 | ||
- | 245 | static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable) |
|
- | 246 | { |
|
- | 247 | u32 val; |
|
- | 248 | ||
- | 249 | mutex_lock(&dev_priv->rps.hw_lock); |
|
- | 250 | ||
- | 251 | val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2); |
|
- | 252 | if (enable) |
|
- | 253 | val &= ~FORCE_DDR_HIGH_FREQ; |
|
- | 254 | else |
|
- | 255 | val |= FORCE_DDR_HIGH_FREQ; |
|
- | 256 | val &= ~FORCE_DDR_LOW_FREQ; |
|
- | 257 | val |= FORCE_DDR_FREQ_REQ_ACK; |
|
- | 258 | vlv_punit_write(dev_priv, PUNIT_REG_DDR_SETUP2, val); |
|
- | 259 | ||
- | 260 | if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) & |
|
- | 261 | FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) |
|
- | 262 | DRM_ERROR("timed out waiting for Punit DDR DVFS request\n"); |
|
- | 263 | ||
- | 264 | mutex_unlock(&dev_priv->rps.hw_lock); |
|
- | 265 | } |
|
- | 266 | ||
- | 267 | static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable) |
|
- | 268 | { |
|
- | 269 | u32 val; |
|
- | 270 | ||
- | 271 | mutex_lock(&dev_priv->rps.hw_lock); |
|
- | 272 | ||
- | 273 | val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); |
|
- | 274 | if (enable) |
|
- | 275 | val |= DSP_MAXFIFO_PM5_ENABLE; |
|
- | 276 | else |
|
- | 277 | val &= ~DSP_MAXFIFO_PM5_ENABLE; |
|
- | 278 | vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val); |
|
- | 279 | ||
- | 280 | mutex_unlock(&dev_priv->rps.hw_lock); |
|
- | 281 | } |
|
- | 282 | ||
- | 283 | #define FW_WM(value, plane) \ |
|
884 | } |
284 | (((value) << DSPFW_ ## plane ## _SHIFT) & DSPFW_ ## plane ## _MASK) |
885 | 285 | ||
886 | void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) |
286 | void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) |
887 | { |
287 | { |
Line 888... | Line 288... | ||
888 | struct drm_device *dev = dev_priv->dev; |
288 | struct drm_device *dev = dev_priv->dev; |
889 | u32 val; |
289 | u32 val; |
- | 290 | ||
- | 291 | if (IS_VALLEYVIEW(dev)) { |
|
890 | 292 | I915_WRITE(FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0); |
|
891 | if (IS_VALLEYVIEW(dev)) { |
293 | POSTING_READ(FW_BLC_SELF_VLV); |
- | 294 | dev_priv->wm.vlv.cxsr = enable; |
|
892 | I915_WRITE(FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0); |
295 | } else if (IS_G4X(dev) || IS_CRESTLINE(dev)) { |
893 | } else if (IS_G4X(dev) || IS_CRESTLINE(dev)) { |
296 | I915_WRITE(FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0); |
894 | I915_WRITE(FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0); |
297 | POSTING_READ(FW_BLC_SELF); |
895 | } else if (IS_PINEVIEW(dev)) { |
298 | } else if (IS_PINEVIEW(dev)) { |
- | 299 | val = I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN; |
|
896 | val = I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN; |
300 | val |= enable ? PINEVIEW_SELF_REFRESH_EN : 0; |
897 | val |= enable ? PINEVIEW_SELF_REFRESH_EN : 0; |
301 | I915_WRITE(DSPFW3, val); |
898 | I915_WRITE(DSPFW3, val); |
302 | POSTING_READ(DSPFW3); |
899 | } else if (IS_I945G(dev) || IS_I945GM(dev)) { |
303 | } else if (IS_I945G(dev) || IS_I945GM(dev)) { |
- | 304 | val = enable ? _MASKED_BIT_ENABLE(FW_BLC_SELF_EN) : |
|
900 | val = enable ? _MASKED_BIT_ENABLE(FW_BLC_SELF_EN) : |
305 | _MASKED_BIT_DISABLE(FW_BLC_SELF_EN); |
901 | _MASKED_BIT_DISABLE(FW_BLC_SELF_EN); |
306 | I915_WRITE(FW_BLC_SELF, val); |
902 | I915_WRITE(FW_BLC_SELF, val); |
307 | POSTING_READ(FW_BLC_SELF); |
903 | } else if (IS_I915GM(dev)) { |
308 | } else if (IS_I915GM(dev)) { |
- | 309 | val = enable ? _MASKED_BIT_ENABLE(INSTPM_SELF_EN) : |
|
904 | val = enable ? _MASKED_BIT_ENABLE(INSTPM_SELF_EN) : |
310 | _MASKED_BIT_DISABLE(INSTPM_SELF_EN); |
905 | _MASKED_BIT_DISABLE(INSTPM_SELF_EN); |
311 | I915_WRITE(INSTPM, val); |
906 | I915_WRITE(INSTPM, val); |
312 | POSTING_READ(INSTPM); |
Line 907... | Line 313... | ||
907 | } else { |
313 | } else { |
908 | return; |
314 | return; |
909 | } |
315 | } |
Line -... | Line 316... | ||
- | 316 | ||
910 | 317 | DRM_DEBUG_KMS("memory self-refresh is %s\n", |
|
911 | DRM_DEBUG_KMS("memory self-refresh is %s\n", |
318 | enable ? "enabled" : "disabled"); |
912 | enable ? "enabled" : "disabled"); |
319 | } |
913 | } |
320 | |
914 | 321 | ||
Line 926... | Line 333... | ||
926 | * A value of 5us seems to be a good balance; safe for very low end |
333 | * A value of 5us seems to be a good balance; safe for very low end |
927 | * platforms but not overly aggressive on lower latency configs. |
334 | * platforms but not overly aggressive on lower latency configs. |
928 | */ |
335 | */ |
929 | static const int pessimal_latency_ns = 5000; |
336 | static const int pessimal_latency_ns = 5000; |
Line -... | Line 337... | ||
- | 337 | ||
- | 338 | #define VLV_FIFO_START(dsparb, dsparb2, lo_shift, hi_shift) \ |
|
- | 339 | ((((dsparb) >> (lo_shift)) & 0xff) | ((((dsparb2) >> (hi_shift)) & 0x1) << 8)) |
|
- | 340 | ||
- | 341 | static int vlv_get_fifo_size(struct drm_device *dev, |
|
- | 342 | enum pipe pipe, int plane) |
|
- | 343 | { |
|
- | 344 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 345 | int sprite0_start, sprite1_start, size; |
|
- | 346 | ||
- | 347 | switch (pipe) { |
|
- | 348 | uint32_t dsparb, dsparb2, dsparb3; |
|
- | 349 | case PIPE_A: |
|
- | 350 | dsparb = I915_READ(DSPARB); |
|
- | 351 | dsparb2 = I915_READ(DSPARB2); |
|
- | 352 | sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 0, 0); |
|
- | 353 | sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 8, 4); |
|
- | 354 | break; |
|
- | 355 | case PIPE_B: |
|
- | 356 | dsparb = I915_READ(DSPARB); |
|
- | 357 | dsparb2 = I915_READ(DSPARB2); |
|
- | 358 | sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 16, 8); |
|
- | 359 | sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 24, 12); |
|
- | 360 | break; |
|
- | 361 | case PIPE_C: |
|
- | 362 | dsparb2 = I915_READ(DSPARB2); |
|
- | 363 | dsparb3 = I915_READ(DSPARB3); |
|
- | 364 | sprite0_start = VLV_FIFO_START(dsparb3, dsparb2, 0, 16); |
|
- | 365 | sprite1_start = VLV_FIFO_START(dsparb3, dsparb2, 8, 20); |
|
- | 366 | break; |
|
- | 367 | default: |
|
- | 368 | return 0; |
|
- | 369 | } |
|
- | 370 | ||
- | 371 | switch (plane) { |
|
- | 372 | case 0: |
|
- | 373 | size = sprite0_start; |
|
- | 374 | break; |
|
- | 375 | case 1: |
|
- | 376 | size = sprite1_start - sprite0_start; |
|
- | 377 | break; |
|
- | 378 | case 2: |
|
- | 379 | size = 512 - 1 - sprite1_start; |
|
- | 380 | break; |
|
- | 381 | default: |
|
- | 382 | return 0; |
|
- | 383 | } |
|
- | 384 | ||
- | 385 | DRM_DEBUG_KMS("Pipe %c %s %c FIFO size: %d\n", |
|
- | 386 | pipe_name(pipe), plane == 0 ? "primary" : "sprite", |
|
- | 387 | plane == 0 ? plane_name(pipe) : sprite_name(pipe, plane - 1), |
|
- | 388 | size); |
|
- | 389 | ||
- | 390 | return size; |
|
- | 391 | } |
|
930 | 392 | ||
931 | static int i9xx_get_fifo_size(struct drm_device *dev, int plane) |
393 | static int i9xx_get_fifo_size(struct drm_device *dev, int plane) |
932 | { |
394 | { |
933 | struct drm_i915_private *dev_priv = dev->dev_private; |
395 | struct drm_i915_private *dev_priv = dev->dev_private; |
934 | uint32_t dsparb = I915_READ(DSPARB); |
396 | uint32_t dsparb = I915_READ(DSPARB); |
Line 1170... | Line 632... | ||
1170 | return; |
632 | return; |
1171 | } |
633 | } |
Line 1172... | Line 634... | ||
1172 | 634 | ||
1173 | crtc = single_enabled_crtc(dev); |
635 | crtc = single_enabled_crtc(dev); |
1174 | if (crtc) { |
636 | if (crtc) { |
1175 | const struct drm_display_mode *adjusted_mode; |
637 | const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; |
1176 | int pixel_size = crtc->primary->fb->bits_per_pixel / 8; |
- | |
1177 | int clock; |
- | |
1178 | - | ||
1179 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
638 | int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8; |
Line 1180... | Line 639... | ||
1180 | clock = adjusted_mode->crtc_clock; |
639 | int clock = adjusted_mode->crtc_clock; |
1181 | 640 | ||
1182 | /* Display SR */ |
641 | /* Display SR */ |
1183 | wm = intel_calculate_wm(clock, &pineview_display_wm, |
642 | wm = intel_calculate_wm(clock, &pineview_display_wm, |
1184 | pineview_display_wm.fifo_size, |
643 | pineview_display_wm.fifo_size, |
1185 | pixel_size, latency->display_sr); |
644 | pixel_size, latency->display_sr); |
1186 | reg = I915_READ(DSPFW1); |
645 | reg = I915_READ(DSPFW1); |
1187 | reg &= ~DSPFW_SR_MASK; |
646 | reg &= ~DSPFW_SR_MASK; |
1188 | reg |= wm << DSPFW_SR_SHIFT; |
647 | reg |= FW_WM(wm, SR); |
Line 1189... | Line 648... | ||
1189 | I915_WRITE(DSPFW1, reg); |
648 | I915_WRITE(DSPFW1, reg); |
1190 | DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); |
649 | DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); |
1191 | 650 | ||
1192 | /* cursor SR */ |
651 | /* cursor SR */ |
1193 | wm = intel_calculate_wm(clock, &pineview_cursor_wm, |
652 | wm = intel_calculate_wm(clock, &pineview_cursor_wm, |
1194 | pineview_display_wm.fifo_size, |
653 | pineview_display_wm.fifo_size, |
1195 | pixel_size, latency->cursor_sr); |
654 | pixel_size, latency->cursor_sr); |
1196 | reg = I915_READ(DSPFW3); |
655 | reg = I915_READ(DSPFW3); |
Line 1197... | Line 656... | ||
1197 | reg &= ~DSPFW_CURSOR_SR_MASK; |
656 | reg &= ~DSPFW_CURSOR_SR_MASK; |
1198 | reg |= (wm & 0x3f) << DSPFW_CURSOR_SR_SHIFT; |
657 | reg |= FW_WM(wm, CURSOR_SR); |
1199 | I915_WRITE(DSPFW3, reg); |
658 | I915_WRITE(DSPFW3, reg); |
1200 | 659 | ||
1201 | /* Display HPLL off SR */ |
660 | /* Display HPLL off SR */ |
1202 | wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm, |
661 | wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm, |
1203 | pineview_display_hplloff_wm.fifo_size, |
662 | pineview_display_hplloff_wm.fifo_size, |
1204 | pixel_size, latency->display_hpll_disable); |
663 | pixel_size, latency->display_hpll_disable); |
Line 1205... | Line 664... | ||
1205 | reg = I915_READ(DSPFW3); |
664 | reg = I915_READ(DSPFW3); |
1206 | reg &= ~DSPFW_HPLL_SR_MASK; |
665 | reg &= ~DSPFW_HPLL_SR_MASK; |
1207 | reg |= wm & DSPFW_HPLL_SR_MASK; |
666 | reg |= FW_WM(wm, HPLL_SR); |
1208 | I915_WRITE(DSPFW3, reg); |
667 | I915_WRITE(DSPFW3, reg); |
1209 | 668 | ||
1210 | /* cursor HPLL off SR */ |
669 | /* cursor HPLL off SR */ |
1211 | wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, |
670 | wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, |
1212 | pineview_display_hplloff_wm.fifo_size, |
671 | pineview_display_hplloff_wm.fifo_size, |
1213 | pixel_size, latency->cursor_hpll_disable); |
672 | pixel_size, latency->cursor_hpll_disable); |
Line 1214... | Line 673... | ||
1214 | reg = I915_READ(DSPFW3); |
673 | reg = I915_READ(DSPFW3); |
1215 | reg &= ~DSPFW_HPLL_CURSOR_MASK; |
674 | reg &= ~DSPFW_HPLL_CURSOR_MASK; |
Line 1243... | Line 702... | ||
1243 | *cursor_wm = cursor->guard_size; |
702 | *cursor_wm = cursor->guard_size; |
1244 | *plane_wm = display->guard_size; |
703 | *plane_wm = display->guard_size; |
1245 | return false; |
704 | return false; |
1246 | } |
705 | } |
Line 1247... | Line 706... | ||
1247 | 706 | ||
1248 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
707 | adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; |
1249 | clock = adjusted_mode->crtc_clock; |
708 | clock = adjusted_mode->crtc_clock; |
1250 | htotal = adjusted_mode->crtc_htotal; |
709 | htotal = adjusted_mode->crtc_htotal; |
1251 | hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; |
710 | hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; |
Line 1252... | Line 711... | ||
1252 | pixel_size = crtc->primary->fb->bits_per_pixel / 8; |
711 | pixel_size = crtc->primary->state->fb->bits_per_pixel / 8; |
1253 | 712 | ||
1254 | /* Use the small buffer method to calculate plane watermark */ |
713 | /* Use the small buffer method to calculate plane watermark */ |
1255 | entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; |
714 | entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; |
Line 1262... | Line 721... | ||
1262 | *plane_wm = display->max_wm; |
721 | *plane_wm = display->max_wm; |
Line 1263... | Line 722... | ||
1263 | 722 | ||
1264 | /* Use the large buffer method to calculate cursor watermark */ |
723 | /* Use the large buffer method to calculate cursor watermark */ |
1265 | line_time_us = max(htotal * 1000 / clock, 1); |
724 | line_time_us = max(htotal * 1000 / clock, 1); |
1266 | line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; |
725 | line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; |
1267 | entries = line_count * to_intel_crtc(crtc)->cursor_width * pixel_size; |
726 | entries = line_count * crtc->cursor->state->crtc_w * pixel_size; |
1268 | tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; |
727 | tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; |
1269 | if (tlb_miss > 0) |
728 | if (tlb_miss > 0) |
1270 | entries += tlb_miss; |
729 | entries += tlb_miss; |
1271 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
730 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
Line 1330... | Line 789... | ||
1330 | *display_wm = *cursor_wm = 0; |
789 | *display_wm = *cursor_wm = 0; |
1331 | return false; |
790 | return false; |
1332 | } |
791 | } |
Line 1333... | Line 792... | ||
1333 | 792 | ||
1334 | crtc = intel_get_crtc_for_plane(dev, plane); |
793 | crtc = intel_get_crtc_for_plane(dev, plane); |
1335 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
794 | adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; |
1336 | clock = adjusted_mode->crtc_clock; |
795 | clock = adjusted_mode->crtc_clock; |
1337 | htotal = adjusted_mode->crtc_htotal; |
796 | htotal = adjusted_mode->crtc_htotal; |
1338 | hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; |
797 | hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; |
Line 1339... | Line 798... | ||
1339 | pixel_size = crtc->primary->fb->bits_per_pixel / 8; |
798 | pixel_size = crtc->primary->state->fb->bits_per_pixel / 8; |
1340 | 799 | ||
1341 | line_time_us = max(htotal * 1000 / clock, 1); |
800 | line_time_us = max(htotal * 1000 / clock, 1); |
Line 1348... | Line 807... | ||
1348 | 807 | ||
1349 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); |
808 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); |
Line 1350... | Line 809... | ||
1350 | *display_wm = entries + display->guard_size; |
809 | *display_wm = entries + display->guard_size; |
1351 | 810 | ||
1352 | /* calculate the self-refresh watermark for display cursor */ |
811 | /* calculate the self-refresh watermark for display cursor */ |
1353 | entries = line_count * pixel_size * to_intel_crtc(crtc)->cursor_width; |
812 | entries = line_count * pixel_size * crtc->cursor->state->crtc_w; |
Line 1354... | Line 813... | ||
1354 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
813 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
1355 | *cursor_wm = entries + cursor->guard_size; |
814 | *cursor_wm = entries + cursor->guard_size; |
1356 | 815 | ||
1357 | return g4x_check_srwm(dev, |
816 | return g4x_check_srwm(dev, |
Line 1358... | Line 817... | ||
1358 | *display_wm, *cursor_wm, |
817 | *display_wm, *cursor_wm, |
1359 | display, cursor); |
818 | display, cursor); |
- | 819 | } |
|
1360 | } |
820 | |
1361 | 821 | #define FW_WM_VLV(value, plane) \ |
|
1362 | static bool vlv_compute_drain_latency(struct drm_crtc *crtc, |
822 | (((value) << DSPFW_ ## plane ## _SHIFT) & DSPFW_ ## plane ## _MASK_VLV) |
1363 | int pixel_size, |
823 | |
1364 | int *prec_mult, |
824 | static void vlv_write_wm_values(struct intel_crtc *crtc, |
1365 | int *drain_latency) |
- | |
Line -... | Line 825... | ||
- | 825 | const struct vlv_wm_values *wm) |
|
1366 | { |
826 | { |
- | 827 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
|
- | 828 | enum pipe pipe = crtc->pipe; |
|
1367 | struct drm_device *dev = crtc->dev; |
829 | |
Line -... | Line 830... | ||
- | 830 | I915_WRITE(VLV_DDL(pipe), |
|
- | 831 | (wm->ddl[pipe].cursor << DDL_CURSOR_SHIFT) | |
|
- | 832 | (wm->ddl[pipe].sprite[1] << DDL_SPRITE_SHIFT(1)) | |
|
- | 833 | (wm->ddl[pipe].sprite[0] << DDL_SPRITE_SHIFT(0)) | |
|
- | 834 | (wm->ddl[pipe].primary << DDL_PLANE_SHIFT)); |
|
- | 835 | ||
- | 836 | I915_WRITE(DSPFW1, |
|
- | 837 | FW_WM(wm->sr.plane, SR) | |
|
1368 | int entries; |
838 | FW_WM(wm->pipe[PIPE_B].cursor, CURSORB) | |
1369 | int clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock; |
839 | FW_WM_VLV(wm->pipe[PIPE_B].primary, PLANEB) | |
- | 840 | FW_WM_VLV(wm->pipe[PIPE_A].primary, PLANEA)); |
|
Line -... | Line 841... | ||
- | 841 | I915_WRITE(DSPFW2, |
|
- | 842 | FW_WM_VLV(wm->pipe[PIPE_A].sprite[1], SPRITEB) | |
|
- | 843 | FW_WM(wm->pipe[PIPE_A].cursor, CURSORA) | |
|
1370 | 844 | FW_WM_VLV(wm->pipe[PIPE_A].sprite[0], SPRITEA)); |
|
1371 | if (WARN(clock == 0, "Pixel clock is zero!\n")) |
845 | I915_WRITE(DSPFW3, |
1372 | return false; |
846 | FW_WM(wm->sr.cursor, CURSOR_SR)); |
- | 847 | ||
- | 848 | if (IS_CHERRYVIEW(dev_priv)) { |
|
- | 849 | I915_WRITE(DSPFW7_CHV, |
|
- | 850 | FW_WM_VLV(wm->pipe[PIPE_B].sprite[1], SPRITED) | |
|
- | 851 | FW_WM_VLV(wm->pipe[PIPE_B].sprite[0], SPRITEC)); |
|
1373 | 852 | I915_WRITE(DSPFW8_CHV, |
|
- | 853 | FW_WM_VLV(wm->pipe[PIPE_C].sprite[1], SPRITEF) | |
|
- | 854 | FW_WM_VLV(wm->pipe[PIPE_C].sprite[0], SPRITEE)); |
|
- | 855 | I915_WRITE(DSPFW9_CHV, |
|
- | 856 | FW_WM_VLV(wm->pipe[PIPE_C].primary, PLANEC) | |
|
- | 857 | FW_WM(wm->pipe[PIPE_C].cursor, CURSORC)); |
|
- | 858 | I915_WRITE(DSPHOWM, |
|
- | 859 | FW_WM(wm->sr.plane >> 9, SR_HI) | |
|
- | 860 | FW_WM(wm->pipe[PIPE_C].sprite[1] >> 8, SPRITEF_HI) | |
|
- | 861 | FW_WM(wm->pipe[PIPE_C].sprite[0] >> 8, SPRITEE_HI) | |
|
1374 | if (WARN(pixel_size == 0, "Pixel size is zero!\n")) |
862 | FW_WM(wm->pipe[PIPE_C].primary >> 8, PLANEC_HI) | |
- | 863 | FW_WM(wm->pipe[PIPE_B].sprite[1] >> 8, SPRITED_HI) | |
|
1375 | return false; |
864 | FW_WM(wm->pipe[PIPE_B].sprite[0] >> 8, SPRITEC_HI) | |
- | 865 | FW_WM(wm->pipe[PIPE_B].primary >> 8, PLANEB_HI) | |
|
- | 866 | FW_WM(wm->pipe[PIPE_A].sprite[1] >> 8, SPRITEB_HI) | |
|
1376 | 867 | FW_WM(wm->pipe[PIPE_A].sprite[0] >> 8, SPRITEA_HI) | |
|
- | 868 | FW_WM(wm->pipe[PIPE_A].primary >> 8, PLANEA_HI)); |
|
- | 869 | } else { |
|
- | 870 | I915_WRITE(DSPFW7, |
|
- | 871 | FW_WM_VLV(wm->pipe[PIPE_B].sprite[1], SPRITED) | |
|
- | 872 | FW_WM_VLV(wm->pipe[PIPE_B].sprite[0], SPRITEC)); |
|
- | 873 | I915_WRITE(DSPHOWM, |
|
- | 874 | FW_WM(wm->sr.plane >> 9, SR_HI) | |
|
- | 875 | FW_WM(wm->pipe[PIPE_B].sprite[1] >> 8, SPRITED_HI) | |
|
- | 876 | FW_WM(wm->pipe[PIPE_B].sprite[0] >> 8, SPRITEC_HI) | |
|
- | 877 | FW_WM(wm->pipe[PIPE_B].primary >> 8, PLANEB_HI) | |
|
- | 878 | FW_WM(wm->pipe[PIPE_A].sprite[1] >> 8, SPRITEB_HI) | |
|
- | 879 | FW_WM(wm->pipe[PIPE_A].sprite[0] >> 8, SPRITEA_HI) | |
|
- | 880 | FW_WM(wm->pipe[PIPE_A].primary >> 8, PLANEA_HI)); |
|
- | 881 | } |
|
- | 882 | ||
- | 883 | /* zero (unused) WM1 watermarks */ |
|
- | 884 | I915_WRITE(DSPFW4, 0); |
|
- | 885 | I915_WRITE(DSPFW5, 0); |
|
- | 886 | I915_WRITE(DSPFW6, 0); |
|
- | 887 | I915_WRITE(DSPHOWM1, 0); |
|
- | 888 | ||
- | 889 | POSTING_READ(DSPFW1); |
|
- | 890 | } |
|
- | 891 | ||
- | 892 | #undef FW_WM_VLV |
|
1377 | entries = DIV_ROUND_UP(clock, 1000) * pixel_size; |
893 | |
- | 894 | enum vlv_wm_level { |
|
- | 895 | VLV_WM_LEVEL_PM2, |
|
- | 896 | VLV_WM_LEVEL_PM5, |
|
- | 897 | VLV_WM_LEVEL_DDR_DVFS, |
|
- | 898 | }; |
|
- | 899 | ||
- | 900 | /* latency must be in 0.1us units. */ |
|
Line 1378... | Line 901... | ||
1378 | if (IS_CHERRYVIEW(dev)) |
901 | static unsigned int vlv_wm_method2(unsigned int pixel_rate, |
- | 902 | unsigned int pipe_htotal, |
|
1379 | *prec_mult = (entries > 128) ? DRAIN_LATENCY_PRECISION_32 : |
903 | unsigned int horiz_pixels, |
Line 1380... | Line 904... | ||
1380 | DRAIN_LATENCY_PRECISION_16; |
904 | unsigned int bytes_per_pixel, |
1381 | else |
905 | unsigned int latency) |
Line -... | Line 906... | ||
- | 906 | { |
|
1382 | *prec_mult = (entries > 128) ? DRAIN_LATENCY_PRECISION_64 : |
907 | unsigned int ret; |
1383 | DRAIN_LATENCY_PRECISION_32; |
908 | |
- | 909 | ret = (latency * pixel_rate) / (pipe_htotal * 10000); |
|
- | 910 | ret = (ret + 1) * horiz_pixels * bytes_per_pixel; |
|
- | 911 | ret = DIV_ROUND_UP(ret, 64); |
|
- | 912 | ||
- | 913 | return ret; |
|
- | 914 | } |
|
- | 915 | ||
- | 916 | static void vlv_setup_wm_latency(struct drm_device *dev) |
|
- | 917 | { |
|
- | 918 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 919 | ||
1384 | *drain_latency = (64 * (*prec_mult) * 4) / entries; |
920 | /* all latencies in usec */ |
- | 921 | dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3; |
|
- | 922 | ||
1385 | 923 | dev_priv->wm.max_level = VLV_WM_LEVEL_PM2; |
|
- | 924 | ||
- | 925 | if (IS_CHERRYVIEW(dev_priv)) { |
|
- | 926 | dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM5] = 12; |
|
- | 927 | dev_priv->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33; |
|
1386 | if (*drain_latency > DRAIN_LATENCY_MASK) |
928 | |
- | 929 | dev_priv->wm.max_level = VLV_WM_LEVEL_DDR_DVFS; |
|
- | 930 | } |
|
- | 931 | } |
|
- | 932 | ||
- | 933 | static uint16_t vlv_compute_wm_level(struct intel_plane *plane, |
|
1387 | *drain_latency = DRAIN_LATENCY_MASK; |
934 | struct intel_crtc *crtc, |
- | 935 | const struct intel_plane_state *state, |
|
- | 936 | int level) |
|
- | 937 | { |
|
- | 938 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
|
- | 939 | int clock, htotal, pixel_size, width, wm; |
|
- | 940 | ||
- | 941 | if (dev_priv->wm.pri_latency[level] == 0) |
|
- | 942 | return USHRT_MAX; |
|
- | 943 | ||
- | 944 | if (!state->visible) |
|
- | 945 | return 0; |
|
- | 946 | ||
- | 947 | pixel_size = drm_format_plane_cpp(state->base.fb->pixel_format, 0); |
|
- | 948 | clock = crtc->config->base.adjusted_mode.crtc_clock; |
|
- | 949 | htotal = crtc->config->base.adjusted_mode.crtc_htotal; |
|
1388 | 950 | width = crtc->config->pipe_src_w; |
|
- | 951 | if (WARN_ON(htotal == 0)) |
|
- | 952 | htotal = 1; |
|
- | 953 | ||
- | 954 | if (plane->base.type == DRM_PLANE_TYPE_CURSOR) { |
|
- | 955 | /* |
|
Line -... | Line 956... | ||
- | 956 | * FIXME the formula gives values that are |
|
- | 957 | * too big for the cursor FIFO, and hence we |
|
- | 958 | * would never be able to use cursors. For |
|
1389 | return true; |
959 | * now just hardcode the watermark. |
1390 | } |
960 | */ |
1391 | 961 | wm = 63; |
|
1392 | /* |
962 | } else { |
1393 | * Update drain latency registers of memory arbiter |
963 | wm = vlv_wm_method2(clock, htotal, width, pixel_size, |
1394 | * |
- | |
1395 | * Valleyview SoC has a new memory arbiter and needs drain latency registers |
964 | dev_priv->wm.pri_latency[level] * 10); |
1396 | * to be programmed. Each plane has a drain latency multiplier and a drain |
965 | } |
1397 | * latency value. |
966 | |
1398 | */ |
- | |
1399 | - | ||
1400 | static void vlv_update_drain_latency(struct drm_crtc *crtc) |
- | |
1401 | { |
- | |
1402 | struct drm_device *dev = crtc->dev; |
- | |
1403 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
Line -... | Line 967... | ||
- | 967 | return min_t(int, wm, USHRT_MAX); |
|
1404 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
968 | } |
1405 | int pixel_size; |
969 | |
- | 970 | static void vlv_compute_fifo(struct intel_crtc *crtc) |
|
- | 971 | { |
|
1406 | int drain_latency; |
972 | struct drm_device *dev = crtc->base.dev; |
- | 973 | struct vlv_wm_state *wm_state = &crtc->wm_state; |
|
- | 974 | struct intel_plane *plane; |
|
- | 975 | unsigned int total_rate = 0; |
|
- | 976 | const int fifo_size = 512 - 1; |
|
- | 977 | int fifo_extra, fifo_left = fifo_size; |
|
1407 | enum pipe pipe = intel_crtc->pipe; |
978 | |
Line 1408... | Line -... | ||
1408 | int plane_prec, prec_mult, plane_dl; |
- | |
1409 | const int high_precision = IS_CHERRYVIEW(dev) ? |
- | |
1410 | DRAIN_LATENCY_PRECISION_32 : DRAIN_LATENCY_PRECISION_64; |
979 | for_each_intel_plane_on_crtc(dev, crtc, plane) { |
1411 | 980 | struct intel_plane_state *state = |
|
1412 | plane_dl = I915_READ(VLV_DDL(pipe)) & ~(DDL_PLANE_PRECISION_HIGH | |
- | |
1413 | DRAIN_LATENCY_MASK | DDL_CURSOR_PRECISION_HIGH | |
- | |
1414 | (DRAIN_LATENCY_MASK << DDL_CURSOR_SHIFT)); |
981 | to_intel_plane_state(plane->base.state); |
1415 | - | ||
1416 | if (!intel_crtc_active(crtc)) { |
- | |
1417 | I915_WRITE(VLV_DDL(pipe), plane_dl); |
982 | |
1418 | return; |
- | |
1419 | } |
- | |
1420 | - | ||
1421 | /* Primary plane Drain Latency */ |
983 | if (plane->base.type == DRM_PLANE_TYPE_CURSOR) |
1422 | pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* BPP */ |
- | |
1423 | if (vlv_compute_drain_latency(crtc, pixel_size, &prec_mult, &drain_latency)) { |
- | |
1424 | plane_prec = (prec_mult == high_precision) ? |
- | |
1425 | DDL_PLANE_PRECISION_HIGH : |
984 | continue; |
1426 | DDL_PLANE_PRECISION_LOW; |
985 | |
1427 | plane_dl |= plane_prec | drain_latency; |
986 | if (state->visible) { |
1428 | } |
- | |
1429 | 987 | wm_state->num_active_planes++; |
|
Line -... | Line 988... | ||
- | 988 | total_rate += drm_format_plane_cpp(state->base.fb->pixel_format, 0); |
|
1430 | /* Cursor Drain Latency |
989 | } |
- | 990 | } |
|
1431 | * BPP is always 4 for cursor |
991 | |
Line 1432... | Line 992... | ||
1432 | */ |
992 | for_each_intel_plane_on_crtc(dev, crtc, plane) { |
- | 993 | struct intel_plane_state *state = |
|
- | 994 | to_intel_plane_state(plane->base.state); |
|
- | 995 | unsigned int rate; |
|
- | 996 | ||
- | 997 | if (plane->base.type == DRM_PLANE_TYPE_CURSOR) { |
|
- | 998 | plane->wm.fifo_size = 63; |
|
- | 999 | continue; |
|
- | 1000 | } |
|
- | 1001 | ||
- | 1002 | if (!state->visible) { |
|
- | 1003 | plane->wm.fifo_size = 0; |
|
- | 1004 | continue; |
|
- | 1005 | } |
|
- | 1006 | ||
- | 1007 | rate = drm_format_plane_cpp(state->base.fb->pixel_format, 0); |
|
- | 1008 | plane->wm.fifo_size = fifo_size * rate / total_rate; |
|
- | 1009 | fifo_left -= plane->wm.fifo_size; |
|
- | 1010 | } |
|
- | 1011 | ||
- | 1012 | fifo_extra = DIV_ROUND_UP(fifo_left, wm_state->num_active_planes ?: 1); |
|
- | 1013 | ||
- | 1014 | /* spread the remainder evenly */ |
|
- | 1015 | for_each_intel_plane_on_crtc(dev, crtc, plane) { |
|
- | 1016 | int plane_extra; |
|
- | 1017 | ||
- | 1018 | if (fifo_left == 0) |
|
- | 1019 | break; |
|
- | 1020 | ||
Line 1433... | Line 1021... | ||
1433 | pixel_size = 4; |
1021 | if (plane->base.type == DRM_PLANE_TYPE_CURSOR) |
1434 | 1022 | continue; |
|
1435 | /* Program cursor DL only if it is enabled */ |
- | |
1436 | if (intel_crtc->cursor_base && |
- | |
1437 | vlv_compute_drain_latency(crtc, pixel_size, &prec_mult, &drain_latency)) { |
1023 | |
1438 | plane_prec = (prec_mult == high_precision) ? |
- | |
1439 | DDL_CURSOR_PRECISION_HIGH : |
- | |
1440 | DDL_CURSOR_PRECISION_LOW; |
- | |
1441 | plane_dl |= plane_prec | (drain_latency << DDL_CURSOR_SHIFT); |
- | |
1442 | } |
1024 | /* give it all to the first plane if none are active */ |
Line -... | Line 1025... | ||
- | 1025 | if (plane->wm.fifo_size == 0 && |
|
- | 1026 | wm_state->num_active_planes) |
|
- | 1027 | continue; |
|
1443 | 1028 | ||
Line 1444... | Line -... | ||
1444 | I915_WRITE(VLV_DDL(pipe), plane_dl); |
- | |
1445 | } |
1029 | plane_extra = min(fifo_extra, fifo_left); |
1446 | 1030 | plane->wm.fifo_size += plane_extra; |
|
1447 | #define single_plane_enabled(mask) is_power_of_2(mask) |
- | |
1448 | - | ||
Line 1449... | Line 1031... | ||
1449 | static void valleyview_update_wm(struct drm_crtc *crtc) |
1031 | fifo_left -= plane_extra; |
- | 1032 | } |
|
- | 1033 | ||
- | 1034 | WARN_ON(fifo_left != 0); |
|
1450 | { |
1035 | } |
- | 1036 | ||
- | 1037 | static void vlv_invert_wms(struct intel_crtc *crtc) |
|
- | 1038 | { |
|
1451 | struct drm_device *dev = crtc->dev; |
1039 | struct vlv_wm_state *wm_state = &crtc->wm_state; |
1452 | static const int sr_latency_ns = 12000; |
1040 | int level; |
- | 1041 | ||
- | 1042 | for (level = 0; level < wm_state->num_levels; level++) { |
|
1453 | struct drm_i915_private *dev_priv = dev->dev_private; |
1043 | struct drm_device *dev = crtc->base.dev; |
- | 1044 | const int sr_fifo_size = INTEL_INFO(dev)->num_pipes * 512 - 1; |
|
- | 1045 | struct intel_plane *plane; |
|
- | 1046 | ||
- | 1047 | wm_state->sr[level].plane = sr_fifo_size - wm_state->sr[level].plane; |
|
- | 1048 | wm_state->sr[level].cursor = 63 - wm_state->sr[level].cursor; |
|
- | 1049 | ||
- | 1050 | for_each_intel_plane_on_crtc(dev, crtc, plane) { |
|
Line 1454... | Line 1051... | ||
1454 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; |
1051 | switch (plane->base.type) { |
- | 1052 | int sprite; |
|
1455 | int plane_sr, cursor_sr; |
1053 | case DRM_PLANE_TYPE_CURSOR: |
1456 | int ignore_plane_sr, ignore_cursor_sr; |
1054 | wm_state->wm[level].cursor = plane->wm.fifo_size - |
1457 | unsigned int enabled = 0; |
1055 | wm_state->wm[level].cursor; |
1458 | bool cxsr_enabled; |
1056 | break; |
- | 1057 | case DRM_PLANE_TYPE_PRIMARY: |
|
- | 1058 | wm_state->wm[level].primary = plane->wm.fifo_size - |
|
1459 | 1059 | wm_state->wm[level].primary; |
|
- | 1060 | break; |
|
1460 | vlv_update_drain_latency(crtc); |
1061 | case DRM_PLANE_TYPE_OVERLAY: |
1461 | 1062 | sprite = plane->plane; |
|
- | 1063 | wm_state->wm[level].sprite[sprite] = plane->wm.fifo_size - |
|
1462 | if (g4x_compute_wm0(dev, PIPE_A, |
1064 | wm_state->wm[level].sprite[sprite]; |
- | 1065 | break; |
|
1463 | &valleyview_wm_info, pessimal_latency_ns, |
1066 | } |
- | 1067 | } |
|
1464 | &valleyview_cursor_wm_info, pessimal_latency_ns, |
1068 | } |
1465 | &planea_wm, &cursora_wm)) |
1069 | } |
- | 1070 | ||
1466 | enabled |= 1 << PIPE_A; |
1071 | static void vlv_compute_wm(struct intel_crtc *crtc) |
1467 | 1072 | { |
|
1468 | if (g4x_compute_wm0(dev, PIPE_B, |
1073 | struct drm_device *dev = crtc->base.dev; |
1469 | &valleyview_wm_info, pessimal_latency_ns, |
1074 | struct vlv_wm_state *wm_state = &crtc->wm_state; |
- | 1075 | struct intel_plane *plane; |
|
1470 | &valleyview_cursor_wm_info, pessimal_latency_ns, |
1076 | int sr_fifo_size = INTEL_INFO(dev)->num_pipes * 512 - 1; |
Line 1471... | Line -... | ||
1471 | &planeb_wm, &cursorb_wm)) |
- | |
1472 | enabled |= 1 << PIPE_B; |
1077 | int level; |
1473 | 1078 | ||
1474 | if (single_plane_enabled(enabled) && |
- | |
1475 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
1079 | memset(wm_state, 0, sizeof(*wm_state)); |
Line 1476... | Line -... | ||
1476 | sr_latency_ns, |
- | |
1477 | &valleyview_wm_info, |
- | |
1478 | &valleyview_cursor_wm_info, |
- | |
1479 | &plane_sr, &ignore_cursor_sr) && |
- | |
1480 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
- | |
1481 | 2*sr_latency_ns, |
1080 | |
1482 | &valleyview_wm_info, |
- | |
1483 | &valleyview_cursor_wm_info, |
- | |
1484 | &ignore_plane_sr, &cursor_sr)) { |
1081 | wm_state->cxsr = crtc->pipe != PIPE_C && crtc->wm.cxsr_allowed; |
1485 | cxsr_enabled = true; |
- | |
1486 | } else { |
- | |
Line -... | Line 1082... | ||
- | 1082 | wm_state->num_levels = to_i915(dev)->wm.max_level + 1; |
|
- | 1083 | ||
- | 1084 | wm_state->num_active_planes = 0; |
|
- | 1085 | ||
- | 1086 | vlv_compute_fifo(crtc); |
|
- | 1087 | ||
- | 1088 | if (wm_state->num_active_planes != 1) |
|
- | 1089 | wm_state->cxsr = false; |
|
- | 1090 | ||
- | 1091 | if (wm_state->cxsr) { |
|
- | 1092 | for (level = 0; level < wm_state->num_levels; level++) { |
|
- | 1093 | wm_state->sr[level].plane = sr_fifo_size; |
|
- | 1094 | wm_state->sr[level].cursor = 63; |
|
- | 1095 | } |
|
- | 1096 | } |
|
- | 1097 | ||
- | 1098 | for_each_intel_plane_on_crtc(dev, crtc, plane) { |
|
- | 1099 | struct intel_plane_state *state = |
|
- | 1100 | to_intel_plane_state(plane->base.state); |
|
- | 1101 | ||
- | 1102 | if (!state->visible) |
|
- | 1103 | continue; |
|
- | 1104 | ||
- | 1105 | /* normal watermarks */ |
|
- | 1106 | for (level = 0; level < wm_state->num_levels; level++) { |
|
- | 1107 | int wm = vlv_compute_wm_level(plane, crtc, state, level); |
|
- | 1108 | int max_wm = plane->base.type == DRM_PLANE_TYPE_CURSOR ? 63 : 511; |
|
- | 1109 | ||
- | 1110 | /* hack */ |
|
1487 | cxsr_enabled = false; |
1111 | if (WARN_ON(level == 0 && wm > max_wm)) |
- | 1112 | wm = max_wm; |
|
- | 1113 | ||
- | 1114 | if (wm > plane->wm.fifo_size) |
|
- | 1115 | break; |
|
- | 1116 | ||
- | 1117 | switch (plane->base.type) { |
|
- | 1118 | int sprite; |
|
- | 1119 | case DRM_PLANE_TYPE_CURSOR: |
|
- | 1120 | wm_state->wm[level].cursor = wm; |
|
- | 1121 | break; |
|
- | 1122 | case DRM_PLANE_TYPE_PRIMARY: |
|
- | 1123 | wm_state->wm[level].primary = wm; |
|
- | 1124 | break; |
|
- | 1125 | case DRM_PLANE_TYPE_OVERLAY: |
|
1488 | intel_set_memory_cxsr(dev_priv, false); |
1126 | sprite = plane->plane; |
- | 1127 | wm_state->wm[level].sprite[sprite] = wm; |
|
- | 1128 | break; |
|
- | 1129 | } |
|
- | 1130 | } |
|
- | 1131 | ||
- | 1132 | wm_state->num_levels = level; |
|
- | 1133 | ||
- | 1134 | if (!wm_state->cxsr) |
|
- | 1135 | continue; |
|
- | 1136 | ||
- | 1137 | /* maxfifo watermarks */ |
|
- | 1138 | switch (plane->base.type) { |
|
- | 1139 | int sprite, level; |
|
- | 1140 | case DRM_PLANE_TYPE_CURSOR: |
|
- | 1141 | for (level = 0; level < wm_state->num_levels; level++) |
|
1489 | plane_sr = cursor_sr = 0; |
1142 | wm_state->sr[level].cursor = |
Line -... | Line 1143... | ||
- | 1143 | wm_state->wm[level].cursor; |
|
- | 1144 | break; |
|
- | 1145 | case DRM_PLANE_TYPE_PRIMARY: |
|
- | 1146 | for (level = 0; level < wm_state->num_levels; level++) |
|
- | 1147 | wm_state->sr[level].plane = |
|
- | 1148 | min(wm_state->sr[level].plane, |
|
1490 | } |
1149 | wm_state->wm[level].primary); |
1491 | 1150 | break; |
|
1492 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, " |
1151 | case DRM_PLANE_TYPE_OVERLAY: |
1493 | "B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", |
- | |
1494 | planea_wm, cursora_wm, |
1152 | sprite = plane->plane; |
1495 | planeb_wm, cursorb_wm, |
1153 | for (level = 0; level < wm_state->num_levels; level++) |
1496 | plane_sr, cursor_sr); |
1154 | wm_state->sr[level].plane = |
1497 | - | ||
1498 | I915_WRITE(DSPFW1, |
- | |
1499 | (plane_sr << DSPFW_SR_SHIFT) | |
- | |
1500 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | |
- | |
Line -... | Line 1155... | ||
- | 1155 | min(wm_state->sr[level].plane, |
|
- | 1156 | wm_state->wm[level].sprite[sprite]); |
|
1501 | (planeb_wm << DSPFW_PLANEB_SHIFT) | |
1157 | break; |
- | 1158 | } |
|
- | 1159 | } |
|
Line 1502... | Line 1160... | ||
1502 | (planea_wm << DSPFW_PLANEA_SHIFT)); |
1160 | |
1503 | I915_WRITE(DSPFW2, |
1161 | /* clear any (partially) filled invalid levels */ |
1504 | (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | |
1162 | for (level = wm_state->num_levels; level < to_i915(dev)->wm.max_level + 1; level++) { |
1505 | (cursora_wm << DSPFW_CURSORA_SHIFT)); |
1163 | memset(&wm_state->wm[level], 0, sizeof(wm_state->wm[level])); |
- | 1164 | memset(&wm_state->sr[level], 0, sizeof(wm_state->sr[level])); |
|
1506 | I915_WRITE(DSPFW3, |
1165 | } |
- | 1166 | ||
Line 1507... | Line -... | ||
1507 | (I915_READ(DSPFW3) & ~DSPFW_CURSOR_SR_MASK) | |
- | |
1508 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
- | |
1509 | - | ||
1510 | if (cxsr_enabled) |
1167 | vlv_invert_wms(crtc); |
1511 | intel_set_memory_cxsr(dev_priv, true); |
- | |
Line -... | Line 1168... | ||
- | 1168 | } |
|
- | 1169 | ||
- | 1170 | #define VLV_FIFO(plane, value) \ |
|
- | 1171 | (((value) << DSPARB_ ## plane ## _SHIFT_VLV) & DSPARB_ ## plane ## _MASK_VLV) |
|
- | 1172 | ||
- | 1173 | static void vlv_pipe_set_fifo_size(struct intel_crtc *crtc) |
|
- | 1174 | { |
|
- | 1175 | struct drm_device *dev = crtc->base.dev; |
|
- | 1176 | struct drm_i915_private *dev_priv = to_i915(dev); |
|
- | 1177 | struct intel_plane *plane; |
|
- | 1178 | int sprite0_start = 0, sprite1_start = 0, fifo_size = 0; |
|
1512 | } |
1179 | |
- | 1180 | for_each_intel_plane_on_crtc(dev, crtc, plane) { |
|
1513 | 1181 | if (plane->base.type == DRM_PLANE_TYPE_CURSOR) { |
|
- | 1182 | WARN_ON(plane->wm.fifo_size != 63); |
|
- | 1183 | continue; |
|
- | 1184 | } |
|
- | 1185 | ||
1514 | static void cherryview_update_wm(struct drm_crtc *crtc) |
1186 | if (plane->base.type == DRM_PLANE_TYPE_PRIMARY) |
- | 1187 | sprite0_start = plane->wm.fifo_size; |
|
- | 1188 | else if (plane->plane == 0) |
|
- | 1189 | sprite1_start = sprite0_start + plane->wm.fifo_size; |
|
- | 1190 | else |
|
- | 1191 | fifo_size = sprite1_start + plane->wm.fifo_size; |
|
- | 1192 | } |
|
- | 1193 | ||
- | 1194 | WARN_ON(fifo_size != 512 - 1); |
|
- | 1195 | ||
1515 | { |
1196 | DRM_DEBUG_KMS("Pipe %c FIFO split %d / %d / %d\n", |
- | 1197 | pipe_name(crtc->pipe), sprite0_start, |
|
- | 1198 | sprite1_start, fifo_size); |
|
- | 1199 | ||
- | 1200 | switch (crtc->pipe) { |
|
- | 1201 | uint32_t dsparb, dsparb2, dsparb3; |
|
- | 1202 | case PIPE_A: |
|
- | 1203 | dsparb = I915_READ(DSPARB); |
|
- | 1204 | dsparb2 = I915_READ(DSPARB2); |
|
- | 1205 | ||
- | 1206 | dsparb &= ~(VLV_FIFO(SPRITEA, 0xff) | |
|
- | 1207 | VLV_FIFO(SPRITEB, 0xff)); |
|
1516 | struct drm_device *dev = crtc->dev; |
1208 | dsparb |= (VLV_FIFO(SPRITEA, sprite0_start) | |
- | 1209 | VLV_FIFO(SPRITEB, sprite1_start)); |
|
- | 1210 | ||
- | 1211 | dsparb2 &= ~(VLV_FIFO(SPRITEA_HI, 0x1) | |
|
- | 1212 | VLV_FIFO(SPRITEB_HI, 0x1)); |
|
- | 1213 | dsparb2 |= (VLV_FIFO(SPRITEA_HI, sprite0_start >> 8) | |
|
- | 1214 | VLV_FIFO(SPRITEB_HI, sprite1_start >> 8)); |
|
- | 1215 | ||
- | 1216 | I915_WRITE(DSPARB, dsparb); |
|
- | 1217 | I915_WRITE(DSPARB2, dsparb2); |
|
- | 1218 | break; |
|
- | 1219 | case PIPE_B: |
|
- | 1220 | dsparb = I915_READ(DSPARB); |
|
Line 1517... | Line 1221... | ||
1517 | static const int sr_latency_ns = 12000; |
1221 | dsparb2 = I915_READ(DSPARB2); |
1518 | struct drm_i915_private *dev_priv = dev->dev_private; |
1222 | |
1519 | int planea_wm, planeb_wm, planec_wm; |
1223 | dsparb &= ~(VLV_FIFO(SPRITEC, 0xff) | |
1520 | int cursora_wm, cursorb_wm, cursorc_wm; |
- | |
1521 | int plane_sr, cursor_sr; |
- | |
1522 | int ignore_plane_sr, ignore_cursor_sr; |
- | |
1523 | unsigned int enabled = 0; |
- | |
1524 | bool cxsr_enabled; |
1224 | VLV_FIFO(SPRITED, 0xff)); |
1525 | - | ||
1526 | vlv_update_drain_latency(crtc); |
- | |
1527 | - | ||
1528 | if (g4x_compute_wm0(dev, PIPE_A, |
1225 | dsparb |= (VLV_FIFO(SPRITEC, sprite0_start) | |
1529 | &valleyview_wm_info, pessimal_latency_ns, |
1226 | VLV_FIFO(SPRITED, sprite1_start)); |
1530 | &valleyview_cursor_wm_info, pessimal_latency_ns, |
- | |
1531 | &planea_wm, &cursora_wm)) |
- | |
1532 | enabled |= 1 << PIPE_A; |
- | |
1533 | 1227 | ||
Line 1534... | Line -... | ||
1534 | if (g4x_compute_wm0(dev, PIPE_B, |
- | |
1535 | &valleyview_wm_info, pessimal_latency_ns, |
- | |
1536 | &valleyview_cursor_wm_info, pessimal_latency_ns, |
- | |
1537 | &planeb_wm, &cursorb_wm)) |
- | |
1538 | enabled |= 1 << PIPE_B; |
- | |
1539 | - | ||
1540 | if (g4x_compute_wm0(dev, PIPE_C, |
1228 | dsparb2 &= ~(VLV_FIFO(SPRITEC_HI, 0xff) | |
Line 1541... | Line -... | ||
1541 | &valleyview_wm_info, pessimal_latency_ns, |
- | |
1542 | &valleyview_cursor_wm_info, pessimal_latency_ns, |
- | |
1543 | &planec_wm, &cursorc_wm)) |
- | |
1544 | enabled |= 1 << PIPE_C; |
- | |
1545 | 1229 | VLV_FIFO(SPRITED_HI, 0xff)); |
|
1546 | if (single_plane_enabled(enabled) && |
- | |
1547 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
- | |
1548 | sr_latency_ns, |
1230 | dsparb2 |= (VLV_FIFO(SPRITEC_HI, sprite0_start >> 8) | |
1549 | &valleyview_wm_info, |
1231 | VLV_FIFO(SPRITED_HI, sprite1_start >> 8)); |
1550 | &valleyview_cursor_wm_info, |
- | |
1551 | &plane_sr, &ignore_cursor_sr) && |
- | |
1552 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
1232 | |
1553 | 2*sr_latency_ns, |
- | |
1554 | &valleyview_wm_info, |
1233 | I915_WRITE(DSPARB, dsparb); |
1555 | &valleyview_cursor_wm_info, |
- | |
1556 | &ignore_plane_sr, &cursor_sr)) { |
- | |
Line -... | Line 1234... | ||
- | 1234 | I915_WRITE(DSPARB2, dsparb2); |
|
1557 | cxsr_enabled = true; |
1235 | break; |
- | 1236 | case PIPE_C: |
|
1558 | } else { |
1237 | dsparb3 = I915_READ(DSPARB3); |
- | 1238 | dsparb2 = I915_READ(DSPARB2); |
|
- | 1239 | ||
- | 1240 | dsparb3 &= ~(VLV_FIFO(SPRITEE, 0xff) | |
|
- | 1241 | VLV_FIFO(SPRITEF, 0xff)); |
|
- | 1242 | dsparb3 |= (VLV_FIFO(SPRITEE, sprite0_start) | |
|
- | 1243 | VLV_FIFO(SPRITEF, sprite1_start)); |
|
- | 1244 | ||
- | 1245 | dsparb2 &= ~(VLV_FIFO(SPRITEE_HI, 0xff) | |
|
- | 1246 | VLV_FIFO(SPRITEF_HI, 0xff)); |
|
- | 1247 | dsparb2 |= (VLV_FIFO(SPRITEE_HI, sprite0_start >> 8) | |
|
1559 | cxsr_enabled = false; |
1248 | VLV_FIFO(SPRITEF_HI, sprite1_start >> 8)); |
Line 1560... | Line 1249... | ||
1560 | intel_set_memory_cxsr(dev_priv, false); |
1249 | |
- | 1250 | I915_WRITE(DSPARB3, dsparb3); |
|
- | 1251 | I915_WRITE(DSPARB2, dsparb2); |
|
1561 | plane_sr = cursor_sr = 0; |
1252 | break; |
- | 1253 | default: |
|
- | 1254 | break; |
|
1562 | } |
1255 | } |
- | 1256 | } |
|
1563 | 1257 | ||
- | 1258 | #undef VLV_FIFO |
|
- | 1259 | ||
1564 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, " |
1260 | static void vlv_merge_wm(struct drm_device *dev, |
- | 1261 | struct vlv_wm_values *wm) |
|
- | 1262 | { |
|
- | 1263 | struct intel_crtc *crtc; |
|
1565 | "B: plane=%d, cursor=%d, C: plane=%d, cursor=%d, " |
1264 | int num_active_crtcs = 0; |
- | 1265 | ||
- | 1266 | wm->level = to_i915(dev)->wm.max_level; |
|
- | 1267 | wm->cxsr = true; |
|
- | 1268 | ||
- | 1269 | for_each_intel_crtc(dev, crtc) { |
|
- | 1270 | const struct vlv_wm_state *wm_state = &crtc->wm_state; |
|
- | 1271 | ||
- | 1272 | if (!crtc->active) |
|
- | 1273 | continue; |
|
1566 | "SR: plane=%d, cursor=%d\n", |
1274 | |
1567 | planea_wm, cursora_wm, |
1275 | if (!wm_state->cxsr) |
1568 | planeb_wm, cursorb_wm, |
1276 | wm->cxsr = false; |
1569 | planec_wm, cursorc_wm, |
1277 | |
1570 | plane_sr, cursor_sr); |
1278 | num_active_crtcs++; |
1571 | 1279 | wm->level = min_t(int, wm->level, wm_state->num_levels - 1); |
|
1572 | I915_WRITE(DSPFW1, |
- | |
1573 | (plane_sr << DSPFW_SR_SHIFT) | |
- | |
1574 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | |
- | |
1575 | (planeb_wm << DSPFW_PLANEB_SHIFT) | |
- | |
1576 | (planea_wm << DSPFW_PLANEA_SHIFT)); |
- | |
1577 | I915_WRITE(DSPFW2, |
1280 | } |
1578 | (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | |
1281 | |
1579 | (cursora_wm << DSPFW_CURSORA_SHIFT)); |
1282 | if (num_active_crtcs != 1) |
1580 | I915_WRITE(DSPFW3, |
1283 | wm->cxsr = false; |
1581 | (I915_READ(DSPFW3) & ~DSPFW_CURSOR_SR_MASK) | |
1284 | |
1582 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
- | |
1583 | I915_WRITE(DSPFW9_CHV, |
1285 | if (num_active_crtcs > 1) |
1584 | (I915_READ(DSPFW9_CHV) & ~(DSPFW_PLANEC_MASK | |
- | |
1585 | DSPFW_CURSORC_MASK)) | |
1286 | wm->level = VLV_WM_LEVEL_PM2; |
1586 | (planec_wm << DSPFW_PLANEC_SHIFT) | |
1287 | |
1587 | (cursorc_wm << DSPFW_CURSORC_SHIFT)); |
- | |
1588 | 1288 | for_each_intel_crtc(dev, crtc) { |
|
Line -... | Line 1289... | ||
- | 1289 | struct vlv_wm_state *wm_state = &crtc->wm_state; |
|
- | 1290 | enum pipe pipe = crtc->pipe; |
|
- | 1291 | ||
- | 1292 | if (!crtc->active) |
|
- | 1293 | continue; |
|
- | 1294 | ||
1589 | if (cxsr_enabled) |
1295 | wm->pipe[pipe] = wm_state->wm[wm->level]; |
- | 1296 | if (wm->cxsr) |
|
- | 1297 | wm->sr = wm_state->sr[wm->level]; |
|
- | 1298 | ||
- | 1299 | wm->ddl[pipe].primary = DDL_PRECISION_HIGH | 2; |
|
- | 1300 | wm->ddl[pipe].sprite[0] = DDL_PRECISION_HIGH | 2; |
|
- | 1301 | wm->ddl[pipe].sprite[1] = DDL_PRECISION_HIGH | 2; |
|
- | 1302 | wm->ddl[pipe].cursor = DDL_PRECISION_HIGH | 2; |
|
- | 1303 | } |
|
- | 1304 | } |
|
- | 1305 | ||
- | 1306 | static void vlv_update_wm(struct drm_crtc *crtc) |
|
- | 1307 | { |
|
- | 1308 | struct drm_device *dev = crtc->dev; |
|
- | 1309 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 1310 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 1311 | enum pipe pipe = intel_crtc->pipe; |
|
- | 1312 | struct vlv_wm_values wm = {}; |
|
- | 1313 | ||
- | 1314 | vlv_compute_wm(intel_crtc); |
|
- | 1315 | vlv_merge_wm(dev, &wm); |
|
- | 1316 | ||
- | 1317 | if (memcmp(&dev_priv->wm.vlv, &wm, sizeof(wm)) == 0) { |
|
- | 1318 | /* FIXME should be part of crtc atomic commit */ |
|
- | 1319 | vlv_pipe_set_fifo_size(intel_crtc); |
|
- | 1320 | return; |
|
- | 1321 | } |
|
- | 1322 | ||
1590 | intel_set_memory_cxsr(dev_priv, true); |
1323 | if (wm.level < VLV_WM_LEVEL_DDR_DVFS && |
Line -... | Line 1324... | ||
- | 1324 | dev_priv->wm.vlv.level >= VLV_WM_LEVEL_DDR_DVFS) |
|
- | 1325 | chv_set_memory_dvfs(dev_priv, false); |
|
1591 | } |
1326 | |
1592 | 1327 | if (wm.level < VLV_WM_LEVEL_PM5 && |
|
1593 | static void valleyview_update_sprite_wm(struct drm_plane *plane, |
1328 | dev_priv->wm.vlv.level >= VLV_WM_LEVEL_PM5) |
1594 | struct drm_crtc *crtc, |
1329 | chv_set_memory_pm5(dev_priv, false); |
1595 | uint32_t sprite_width, |
1330 | |
Line 1663... | Line 1398... | ||
1663 | planea_wm, cursora_wm, |
1398 | planea_wm, cursora_wm, |
1664 | planeb_wm, cursorb_wm, |
1399 | planeb_wm, cursorb_wm, |
1665 | plane_sr, cursor_sr); |
1400 | plane_sr, cursor_sr); |
Line 1666... | Line 1401... | ||
1666 | 1401 | ||
1667 | I915_WRITE(DSPFW1, |
1402 | I915_WRITE(DSPFW1, |
1668 | (plane_sr << DSPFW_SR_SHIFT) | |
1403 | FW_WM(plane_sr, SR) | |
1669 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | |
1404 | FW_WM(cursorb_wm, CURSORB) | |
1670 | (planeb_wm << DSPFW_PLANEB_SHIFT) | |
1405 | FW_WM(planeb_wm, PLANEB) | |
1671 | (planea_wm << DSPFW_PLANEA_SHIFT)); |
1406 | FW_WM(planea_wm, PLANEA)); |
1672 | I915_WRITE(DSPFW2, |
1407 | I915_WRITE(DSPFW2, |
1673 | (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | |
1408 | (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | |
1674 | (cursora_wm << DSPFW_CURSORA_SHIFT)); |
1409 | FW_WM(cursora_wm, CURSORA)); |
1675 | /* HPLL off in SR has some issues on G4x... disable it */ |
1410 | /* HPLL off in SR has some issues on G4x... disable it */ |
1676 | I915_WRITE(DSPFW3, |
1411 | I915_WRITE(DSPFW3, |
1677 | (I915_READ(DSPFW3) & ~(DSPFW_HPLL_SR_EN | DSPFW_CURSOR_SR_MASK)) | |
1412 | (I915_READ(DSPFW3) & ~(DSPFW_HPLL_SR_EN | DSPFW_CURSOR_SR_MASK)) | |
Line 1678... | Line 1413... | ||
1678 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
1413 | FW_WM(cursor_sr, CURSOR_SR)); |
1679 | 1414 | ||
1680 | if (cxsr_enabled) |
1415 | if (cxsr_enabled) |
Line 1693... | Line 1428... | ||
1693 | /* Calc sr entries for one plane configs */ |
1428 | /* Calc sr entries for one plane configs */ |
1694 | crtc = single_enabled_crtc(dev); |
1429 | crtc = single_enabled_crtc(dev); |
1695 | if (crtc) { |
1430 | if (crtc) { |
1696 | /* self-refresh has much higher latency */ |
1431 | /* self-refresh has much higher latency */ |
1697 | static const int sr_latency_ns = 12000; |
1432 | static const int sr_latency_ns = 12000; |
1698 | const struct drm_display_mode *adjusted_mode = |
1433 | const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; |
1699 | &to_intel_crtc(crtc)->config.adjusted_mode; |
- | |
1700 | int clock = adjusted_mode->crtc_clock; |
1434 | int clock = adjusted_mode->crtc_clock; |
1701 | int htotal = adjusted_mode->crtc_htotal; |
1435 | int htotal = adjusted_mode->crtc_htotal; |
1702 | int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; |
1436 | int hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; |
1703 | int pixel_size = crtc->primary->fb->bits_per_pixel / 8; |
1437 | int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8; |
1704 | unsigned long line_time_us; |
1438 | unsigned long line_time_us; |
1705 | int entries; |
1439 | int entries; |
Line 1706... | Line 1440... | ||
1706 | 1440 | ||
Line 1716... | Line 1450... | ||
1716 | srwm &= 0x1ff; |
1450 | srwm &= 0x1ff; |
1717 | DRM_DEBUG_KMS("self-refresh entries: %d, wm: %d\n", |
1451 | DRM_DEBUG_KMS("self-refresh entries: %d, wm: %d\n", |
1718 | entries, srwm); |
1452 | entries, srwm); |
Line 1719... | Line 1453... | ||
1719 | 1453 | ||
1720 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
1454 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
1721 | pixel_size * to_intel_crtc(crtc)->cursor_width; |
1455 | pixel_size * crtc->cursor->state->crtc_w; |
1722 | entries = DIV_ROUND_UP(entries, |
1456 | entries = DIV_ROUND_UP(entries, |
1723 | i965_cursor_wm_info.cacheline_size); |
1457 | i965_cursor_wm_info.cacheline_size); |
1724 | cursor_sr = i965_cursor_wm_info.fifo_size - |
1458 | cursor_sr = i965_cursor_wm_info.fifo_size - |
Line 1739... | Line 1473... | ||
1739 | 1473 | ||
1740 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", |
1474 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", |
Line 1741... | Line 1475... | ||
1741 | srwm); |
1475 | srwm); |
1742 | 1476 | ||
1743 | /* 965 has limitations... */ |
1477 | /* 965 has limitations... */ |
1744 | I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | |
1478 | I915_WRITE(DSPFW1, FW_WM(srwm, SR) | |
1745 | (8 << DSPFW_CURSORB_SHIFT) | |
1479 | FW_WM(8, CURSORB) | |
1746 | (8 << DSPFW_PLANEB_SHIFT) | |
1480 | FW_WM(8, PLANEB) | |
1747 | (8 << DSPFW_PLANEA_SHIFT)); |
1481 | FW_WM(8, PLANEA)); |
1748 | I915_WRITE(DSPFW2, (8 << DSPFW_CURSORA_SHIFT) | |
1482 | I915_WRITE(DSPFW2, FW_WM(8, CURSORA) | |
1749 | (8 << DSPFW_PLANEC_SHIFT_OLD)); |
1483 | FW_WM(8, PLANEC_OLD)); |
Line 1750... | Line 1484... | ||
1750 | /* update cursor SR watermark */ |
1484 | /* update cursor SR watermark */ |
1751 | I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
1485 | I915_WRITE(DSPFW3, FW_WM(cursor_sr, CURSOR_SR)); |
1752 | 1486 | ||
Line -... | Line 1487... | ||
- | 1487 | if (cxsr_enabled) |
|
- | 1488 | intel_set_memory_cxsr(dev_priv, true); |
|
1753 | if (cxsr_enabled) |
1489 | } |
1754 | intel_set_memory_cxsr(dev_priv, true); |
1490 | |
1755 | } |
1491 | #undef FW_WM |
1756 | 1492 | ||
1757 | static void i9xx_update_wm(struct drm_crtc *unused_crtc) |
1493 | static void i9xx_update_wm(struct drm_crtc *unused_crtc) |
Line 1775... | Line 1511... | ||
1775 | 1511 | ||
1776 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); |
1512 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); |
1777 | crtc = intel_get_crtc_for_plane(dev, 0); |
1513 | crtc = intel_get_crtc_for_plane(dev, 0); |
1778 | if (intel_crtc_active(crtc)) { |
1514 | if (intel_crtc_active(crtc)) { |
1779 | const struct drm_display_mode *adjusted_mode; |
1515 | const struct drm_display_mode *adjusted_mode; |
1780 | int cpp = crtc->primary->fb->bits_per_pixel / 8; |
1516 | int cpp = crtc->primary->state->fb->bits_per_pixel / 8; |
1781 | if (IS_GEN2(dev)) |
1517 | if (IS_GEN2(dev)) |
Line 1782... | Line 1518... | ||
1782 | cpp = 4; |
1518 | cpp = 4; |
1783 | 1519 | ||
1784 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
1520 | adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; |
1785 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
1521 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
1786 | wm_info, fifo_size, cpp, |
1522 | wm_info, fifo_size, cpp, |
1787 | pessimal_latency_ns); |
1523 | pessimal_latency_ns); |
Line 1797... | Line 1533... | ||
1797 | 1533 | ||
1798 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); |
1534 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); |
1799 | crtc = intel_get_crtc_for_plane(dev, 1); |
1535 | crtc = intel_get_crtc_for_plane(dev, 1); |
1800 | if (intel_crtc_active(crtc)) { |
1536 | if (intel_crtc_active(crtc)) { |
1801 | const struct drm_display_mode *adjusted_mode; |
1537 | const struct drm_display_mode *adjusted_mode; |
1802 | int cpp = crtc->primary->fb->bits_per_pixel / 8; |
1538 | int cpp = crtc->primary->state->fb->bits_per_pixel / 8; |
1803 | if (IS_GEN2(dev)) |
1539 | if (IS_GEN2(dev)) |
Line 1804... | Line 1540... | ||
1804 | cpp = 4; |
1540 | cpp = 4; |
1805 | 1541 | ||
1806 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
1542 | adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; |
1807 | planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
1543 | planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
1808 | wm_info, fifo_size, cpp, |
1544 | wm_info, fifo_size, cpp, |
1809 | pessimal_latency_ns); |
1545 | pessimal_latency_ns); |
Line 1820... | Line 1556... | ||
1820 | DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); |
1556 | DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); |
Line 1821... | Line 1557... | ||
1821 | 1557 | ||
1822 | if (IS_I915GM(dev) && enabled) { |
1558 | if (IS_I915GM(dev) && enabled) { |
Line 1823... | Line 1559... | ||
1823 | struct drm_i915_gem_object *obj; |
1559 | struct drm_i915_gem_object *obj; |
Line 1824... | Line 1560... | ||
1824 | 1560 | ||
1825 | obj = intel_fb_obj(enabled->primary->fb); |
1561 | obj = intel_fb_obj(enabled->primary->state->fb); |
1826 | 1562 | ||
1827 | /* self-refresh seems busted with untiled */ |
1563 | /* self-refresh seems busted with untiled */ |
Line 1839... | Line 1575... | ||
1839 | 1575 | ||
1840 | /* Calc sr entries for one plane configs */ |
1576 | /* Calc sr entries for one plane configs */ |
1841 | if (HAS_FW_BLC(dev) && enabled) { |
1577 | if (HAS_FW_BLC(dev) && enabled) { |
1842 | /* self-refresh has much higher latency */ |
1578 | /* self-refresh has much higher latency */ |
1843 | static const int sr_latency_ns = 6000; |
- | |
1844 | const struct drm_display_mode *adjusted_mode = |
1579 | static const int sr_latency_ns = 6000; |
1845 | &to_intel_crtc(enabled)->config.adjusted_mode; |
1580 | const struct drm_display_mode *adjusted_mode = &to_intel_crtc(enabled)->config->base.adjusted_mode; |
1846 | int clock = adjusted_mode->crtc_clock; |
1581 | int clock = adjusted_mode->crtc_clock; |
1847 | int htotal = adjusted_mode->crtc_htotal; |
1582 | int htotal = adjusted_mode->crtc_htotal; |
1848 | int hdisplay = to_intel_crtc(enabled)->config.pipe_src_w; |
1583 | int hdisplay = to_intel_crtc(enabled)->config->pipe_src_w; |
1849 | int pixel_size = enabled->primary->fb->bits_per_pixel / 8; |
1584 | int pixel_size = enabled->primary->state->fb->bits_per_pixel / 8; |
1850 | unsigned long line_time_us; |
1585 | unsigned long line_time_us; |
Line 1851... | Line 1586... | ||
1851 | int entries; |
1586 | int entries; |
Line 1896... | Line 1631... | ||
1896 | 1631 | ||
1897 | crtc = single_enabled_crtc(dev); |
1632 | crtc = single_enabled_crtc(dev); |
1898 | if (crtc == NULL) |
1633 | if (crtc == NULL) |
Line 1899... | Line 1634... | ||
1899 | return; |
1634 | return; |
1900 | 1635 | ||
1901 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
1636 | adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; |
1902 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
1637 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
1903 | &i845_wm_info, |
1638 | &i845_wm_info, |
1904 | dev_priv->display.get_fifo_size(dev, 0), |
1639 | dev_priv->display.get_fifo_size(dev, 0), |
Line 1909... | Line 1644... | ||
1909 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm); |
1644 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm); |
Line 1910... | Line 1645... | ||
1910 | 1645 | ||
1911 | I915_WRITE(FW_BLC, fwater_lo); |
1646 | I915_WRITE(FW_BLC, fwater_lo); |
Line 1912... | Line 1647... | ||
1912 | } |
1647 | } |
1913 | - | ||
1914 | static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev, |
1648 | |
1915 | struct drm_crtc *crtc) |
- | |
1916 | { |
1649 | uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config) |
Line 1917... | Line 1650... | ||
1917 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1650 | { |
Line 1918... | Line 1651... | ||
1918 | uint32_t pixel_rate; |
1651 | uint32_t pixel_rate; |
1919 | 1652 | ||
Line 1920... | Line 1653... | ||
1920 | pixel_rate = intel_crtc->config.adjusted_mode.crtc_clock; |
1653 | pixel_rate = pipe_config->base.adjusted_mode.crtc_clock; |
1921 | 1654 | ||
1922 | /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to |
1655 | /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to |
- | 1656 | * adjust the pixel_rate here. */ |
|
- | 1657 | ||
- | 1658 | if (pipe_config->pch_pfit.enabled) { |
|
Line 1923... | Line -... | ||
1923 | * adjust the pixel_rate here. */ |
- | |
1924 | - | ||
1925 | if (intel_crtc->config.pch_pfit.enabled) { |
1659 | uint64_t pipe_w, pipe_h, pfit_w, pfit_h; |
1926 | uint64_t pipe_w, pipe_h, pfit_w, pfit_h; |
1660 | uint32_t pfit_size = pipe_config->pch_pfit.size; |
1927 | uint32_t pfit_size = intel_crtc->config.pch_pfit.size; |
1661 | |
1928 | 1662 | pipe_w = pipe_config->pipe_src_w; |
|
1929 | pipe_w = intel_crtc->config.pipe_src_w; |
1663 | pipe_h = pipe_config->pipe_src_h; |
Line 1982... | Line 1716... | ||
1982 | struct skl_pipe_wm_parameters { |
1716 | struct skl_pipe_wm_parameters { |
1983 | bool active; |
1717 | bool active; |
1984 | uint32_t pipe_htotal; |
1718 | uint32_t pipe_htotal; |
1985 | uint32_t pixel_rate; /* in KHz */ |
1719 | uint32_t pixel_rate; /* in KHz */ |
1986 | struct intel_plane_wm_parameters plane[I915_MAX_PLANES]; |
1720 | struct intel_plane_wm_parameters plane[I915_MAX_PLANES]; |
1987 | struct intel_plane_wm_parameters cursor; |
- | |
1988 | }; |
- | |
1989 | - | ||
1990 | struct ilk_pipe_wm_parameters { |
- | |
1991 | bool active; |
- | |
1992 | uint32_t pipe_htotal; |
- | |
1993 | uint32_t pixel_rate; |
- | |
1994 | struct intel_plane_wm_parameters pri; |
- | |
1995 | struct intel_plane_wm_parameters spr; |
- | |
1996 | struct intel_plane_wm_parameters cur; |
- | |
1997 | }; |
1721 | }; |
Line 1998... | Line 1722... | ||
1998 | 1722 | ||
1999 | struct ilk_wm_maximums { |
1723 | struct ilk_wm_maximums { |
2000 | uint16_t pri; |
1724 | uint16_t pri; |
Line 2012... | Line 1736... | ||
2012 | 1736 | ||
2013 | /* |
1737 | /* |
2014 | * For both WM_PIPE and WM_LP. |
1738 | * For both WM_PIPE and WM_LP. |
2015 | * mem_value must be in 0.1us units. |
1739 | * mem_value must be in 0.1us units. |
2016 | */ |
1740 | */ |
- | 1741 | static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate, |
|
2017 | static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params, |
1742 | const struct intel_plane_state *pstate, |
2018 | uint32_t mem_value, |
1743 | uint32_t mem_value, |
2019 | bool is_lp) |
1744 | bool is_lp) |
- | 1745 | { |
|
2020 | { |
1746 | int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; |
Line 2021... | Line 1747... | ||
2021 | uint32_t method1, method2; |
1747 | uint32_t method1, method2; |
2022 | 1748 | ||
Line 2023... | Line 1749... | ||
2023 | if (!params->active || !params->pri.enabled) |
1749 | if (!cstate->base.active || !pstate->visible) |
2024 | return 0; |
- | |
2025 | - | ||
Line 2026... | Line 1750... | ||
2026 | method1 = ilk_wm_method1(params->pixel_rate, |
1750 | return 0; |
2027 | params->pri.bytes_per_pixel, |
1751 | |
Line 2028... | Line 1752... | ||
2028 | mem_value); |
1752 | method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value); |
2029 | 1753 | ||
2030 | if (!is_lp) |
1754 | if (!is_lp) |
2031 | return method1; |
1755 | return method1; |
2032 | 1756 | ||
Line 2033... | Line 1757... | ||
2033 | method2 = ilk_wm_method2(params->pixel_rate, |
1757 | method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate), |
2034 | params->pipe_htotal, |
1758 | cstate->base.adjusted_mode.crtc_htotal, |
Line 2035... | Line 1759... | ||
2035 | params->pri.horiz_pixels, |
1759 | drm_rect_width(&pstate->dst), |
2036 | params->pri.bytes_per_pixel, |
1760 | bpp, |
2037 | mem_value); |
1761 | mem_value); |
2038 | 1762 | ||
2039 | return min(method1, method2); |
1763 | return min(method1, method2); |
- | 1764 | } |
|
2040 | } |
1765 | |
2041 | 1766 | /* |
|
- | 1767 | * For both WM_PIPE and WM_LP. |
|
2042 | /* |
1768 | * mem_value must be in 0.1us units. |
Line 2043... | Line 1769... | ||
2043 | * For both WM_PIPE and WM_LP. |
1769 | */ |
2044 | * mem_value must be in 0.1us units. |
1770 | static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate, |
Line 2045... | Line 1771... | ||
2045 | */ |
1771 | const struct intel_plane_state *pstate, |
2046 | static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params, |
- | |
2047 | uint32_t mem_value) |
- | |
2048 | { |
1772 | uint32_t mem_value) |
2049 | uint32_t method1, method2; |
1773 | { |
2050 | 1774 | int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; |
|
2051 | if (!params->active || !params->spr.enabled) |
1775 | uint32_t method1, method2; |
2052 | return 0; |
1776 | |
2053 | 1777 | if (!cstate->base.active || !pstate->visible) |
|
2054 | method1 = ilk_wm_method1(params->pixel_rate, |
1778 | return 0; |
Line 2055... | Line 1779... | ||
2055 | params->spr.bytes_per_pixel, |
1779 | |
2056 | mem_value); |
1780 | method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value); |
2057 | method2 = ilk_wm_method2(params->pixel_rate, |
1781 | method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate), |
2058 | params->pipe_htotal, |
1782 | cstate->base.adjusted_mode.crtc_htotal, |
2059 | params->spr.horiz_pixels, |
1783 | drm_rect_width(&pstate->dst), |
- | 1784 | bpp, |
|
2060 | params->spr.bytes_per_pixel, |
1785 | mem_value); |
2061 | mem_value); |
1786 | return min(method1, method2); |
- | 1787 | } |
|
- | 1788 | ||
2062 | return min(method1, method2); |
1789 | /* |
2063 | } |
1790 | * For both WM_PIPE and WM_LP. |
Line 2064... | Line 1791... | ||
2064 | 1791 | * mem_value must be in 0.1us units. |
|
2065 | /* |
1792 | */ |
2066 | * For both WM_PIPE and WM_LP. |
1793 | static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate, |
2067 | * mem_value must be in 0.1us units. |
1794 | const struct intel_plane_state *pstate, |
2068 | */ |
1795 | uint32_t mem_value) |
2069 | static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params, |
1796 | { |
Line 2070... | Line 1797... | ||
2070 | uint32_t mem_value) |
1797 | int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; |
2071 | { |
1798 | |
- | 1799 | if (!cstate->base.active || !pstate->visible) |
|
2072 | if (!params->active || !params->cur.enabled) |
1800 | return 0; |
2073 | return 0; |
1801 | |
- | 1802 | return ilk_wm_method2(ilk_pipe_pixel_rate(cstate), |
|
- | 1803 | cstate->base.adjusted_mode.crtc_htotal, |
|
2074 | 1804 | drm_rect_width(&pstate->dst), |
|
2075 | return ilk_wm_method2(params->pixel_rate, |
1805 | bpp, |
Line 2076... | Line 1806... | ||
2076 | params->pipe_htotal, |
1806 | mem_value); |
2077 | params->cur.horiz_pixels, |
- | |
2078 | params->cur.bytes_per_pixel, |
- | |
2079 | mem_value); |
1807 | } |
Line 2080... | Line 1808... | ||
2080 | } |
1808 | |
2081 | 1809 | /* Only for WM_LP. */ |
|
2082 | /* Only for WM_LP. */ |
1810 | static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate, |
Line 2251... | Line 1979... | ||
2251 | 1979 | ||
2252 | return ret; |
1980 | return ret; |
Line 2253... | Line 1981... | ||
2253 | } |
1981 | } |
- | 1982 | ||
2254 | 1983 | static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, |
|
2255 | static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, |
1984 | const struct intel_crtc *intel_crtc, |
2256 | int level, |
1985 | int level, |
2257 | const struct ilk_pipe_wm_parameters *p, |
1986 | struct intel_crtc_state *cstate, |
- | 1987 | struct intel_wm_level *result) |
|
2258 | struct intel_wm_level *result) |
1988 | { |
2259 | { |
1989 | struct intel_plane *intel_plane; |
2260 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; |
1990 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; |
Line 2261... | Line 1991... | ||
2261 | uint16_t spr_latency = dev_priv->wm.spr_latency[level]; |
1991 | uint16_t spr_latency = dev_priv->wm.spr_latency[level]; |
Line 2266... | Line 1996... | ||
2266 | pri_latency *= 5; |
1996 | pri_latency *= 5; |
2267 | spr_latency *= 5; |
1997 | spr_latency *= 5; |
2268 | cur_latency *= 5; |
1998 | cur_latency *= 5; |
2269 | } |
1999 | } |
Line -... | Line 2000... | ||
- | 2000 | ||
- | 2001 | for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) { |
|
- | 2002 | struct intel_plane_state *pstate = |
|
- | 2003 | to_intel_plane_state(intel_plane->base.state); |
|
- | 2004 | ||
- | 2005 | switch (intel_plane->base.type) { |
|
2270 | 2006 | case DRM_PLANE_TYPE_PRIMARY: |
|
- | 2007 | result->pri_val = ilk_compute_pri_wm(cstate, pstate, |
|
- | 2008 | pri_latency, |
|
2271 | result->pri_val = ilk_compute_pri_wm(p, pri_latency, level); |
2009 | level); |
- | 2010 | result->fbc_val = ilk_compute_fbc_wm(cstate, pstate, |
|
- | 2011 | result->pri_val); |
|
- | 2012 | break; |
|
2272 | result->spr_val = ilk_compute_spr_wm(p, spr_latency); |
2013 | case DRM_PLANE_TYPE_OVERLAY: |
- | 2014 | result->spr_val = ilk_compute_spr_wm(cstate, pstate, |
|
- | 2015 | spr_latency); |
|
- | 2016 | break; |
|
2273 | result->cur_val = ilk_compute_cur_wm(p, cur_latency); |
2017 | case DRM_PLANE_TYPE_CURSOR: |
- | 2018 | result->cur_val = ilk_compute_cur_wm(cstate, pstate, |
|
- | 2019 | cur_latency); |
|
- | 2020 | break; |
|
- | 2021 | } |
|
- | 2022 | } |
|
2274 | result->fbc_val = ilk_compute_fbc_wm(p, result->pri_val); |
2023 | |
2275 | result->enable = true; |
2024 | result->enable = true; |
Line 2276... | Line 2025... | ||
2276 | } |
2025 | } |
2277 | 2026 | ||
2278 | static uint32_t |
2027 | static uint32_t |
2279 | hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) |
2028 | hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) |
2280 | { |
2029 | { |
2281 | struct drm_i915_private *dev_priv = dev->dev_private; |
2030 | struct drm_i915_private *dev_priv = dev->dev_private; |
2282 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2031 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
Line 2283... | Line 2032... | ||
2283 | struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode; |
2032 | const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; |
2284 | u32 linetime, ips_linetime; |
2033 | u32 linetime, ips_linetime; |
Line 2285... | Line 2034... | ||
2285 | 2034 | ||
2286 | if (!intel_crtc_active(crtc)) |
2035 | if (!intel_crtc->active) |
2287 | return 0; |
2036 | return 0; |
2288 | 2037 | ||
2289 | /* The WM are computed with base on how long it takes to fill a single |
2038 | /* The WM are computed with base on how long it takes to fill a single |
2290 | * row at the given clock rate, multiplied by 8. |
2039 | * row at the given clock rate, multiplied by 8. |
2291 | * */ |
2040 | * */ |
Line 2292... | Line 2041... | ||
2292 | linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8, |
2041 | linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8, |
2293 | mode->crtc_clock); |
2042 | adjusted_mode->crtc_clock); |
2294 | ips_linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8, |
2043 | ips_linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8, |
Line 2347... | Line 2096... | ||
2347 | GEN9_MEM_LATENCY_LEVEL_MASK; |
2096 | GEN9_MEM_LATENCY_LEVEL_MASK; |
2348 | wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & |
2097 | wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & |
2349 | GEN9_MEM_LATENCY_LEVEL_MASK; |
2098 | GEN9_MEM_LATENCY_LEVEL_MASK; |
Line 2350... | Line 2099... | ||
2350 | 2099 | ||
- | 2100 | /* |
|
- | 2101 | * WaWmMemoryReadLatency:skl |
|
2351 | /* |
2102 | * |
2352 | * punit doesn't take into account the read latency so we need |
2103 | * punit doesn't take into account the read latency so we need |
2353 | * to add 2us to the various latency levels we retrieve from |
2104 | * to add 2us to the various latency levels we retrieve from |
2354 | * the punit. |
2105 | * the punit. |
2355 | * - W0 is a bit special in that it's the only level that |
2106 | * - W0 is a bit special in that it's the only level that |
Line 2419... | Line 2170... | ||
2419 | } |
2170 | } |
Line 2420... | Line 2171... | ||
2420 | 2171 | ||
2421 | int ilk_wm_max_level(const struct drm_device *dev) |
2172 | int ilk_wm_max_level(const struct drm_device *dev) |
2422 | { |
2173 | { |
2423 | /* how many WM levels are we expecting */ |
2174 | /* how many WM levels are we expecting */ |
2424 | if (IS_GEN9(dev)) |
2175 | if (INTEL_INFO(dev)->gen >= 9) |
2425 | return 7; |
2176 | return 7; |
2426 | else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
2177 | else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
2427 | return 4; |
2178 | return 4; |
2428 | else if (INTEL_INFO(dev)->gen >= 6) |
2179 | else if (INTEL_INFO(dev)->gen >= 6) |
Line 2526... | Line 2277... | ||
2526 | 2277 | ||
2527 | intel_read_wm_latency(dev, dev_priv->wm.skl_latency); |
2278 | intel_read_wm_latency(dev, dev_priv->wm.skl_latency); |
2528 | intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); |
2279 | intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); |
Line 2529... | Line -... | ||
2529 | } |
- | |
2530 | - | ||
2531 | static void ilk_compute_wm_parameters(struct drm_crtc *crtc, |
- | |
2532 | struct ilk_pipe_wm_parameters *p) |
- | |
2533 | { |
- | |
2534 | struct drm_device *dev = crtc->dev; |
- | |
2535 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
2536 | enum pipe pipe = intel_crtc->pipe; |
- | |
2537 | struct drm_plane *plane; |
- | |
2538 | - | ||
2539 | if (!intel_crtc_active(crtc)) |
- | |
2540 | return; |
- | |
2541 | - | ||
2542 | p->active = true; |
- | |
2543 | p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal; |
- | |
2544 | p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); |
- | |
2545 | p->pri.bytes_per_pixel = crtc->primary->fb->bits_per_pixel / 8; |
- | |
2546 | p->cur.bytes_per_pixel = 4; |
- | |
2547 | p->pri.horiz_pixels = intel_crtc->config.pipe_src_w; |
- | |
2548 | p->cur.horiz_pixels = intel_crtc->cursor_width; |
- | |
2549 | /* TODO: for now, assume primary and cursor planes are always enabled. */ |
- | |
2550 | p->pri.enabled = true; |
- | |
2551 | p->cur.enabled = true; |
- | |
2552 | - | ||
2553 | drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { |
- | |
2554 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
2555 | - | ||
2556 | if (intel_plane->pipe == pipe) { |
- | |
2557 | p->spr = intel_plane->wm; |
- | |
2558 | break; |
- | |
2559 | } |
- | |
2560 | } |
- | |
2561 | } |
2280 | } |
2562 | 2281 | ||
2563 | static void ilk_compute_wm_config(struct drm_device *dev, |
2282 | static void ilk_compute_wm_config(struct drm_device *dev, |
2564 | struct intel_wm_config *config) |
2283 | struct intel_wm_config *config) |
Line 2577... | Line 2296... | ||
2577 | config->num_pipes_active++; |
2296 | config->num_pipes_active++; |
2578 | } |
2297 | } |
2579 | } |
2298 | } |
Line 2580... | Line 2299... | ||
2580 | 2299 | ||
2581 | /* Compute new watermarks for the pipe */ |
2300 | /* Compute new watermarks for the pipe */ |
2582 | static bool intel_compute_pipe_wm(struct drm_crtc *crtc, |
- | |
2583 | const struct ilk_pipe_wm_parameters *params, |
2301 | static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate, |
2584 | struct intel_pipe_wm *pipe_wm) |
2302 | struct intel_pipe_wm *pipe_wm) |
- | 2303 | { |
|
2585 | { |
2304 | struct drm_crtc *crtc = cstate->base.crtc; |
2586 | struct drm_device *dev = crtc->dev; |
2305 | struct drm_device *dev = crtc->dev; |
- | 2306 | const struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 2307 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 2308 | struct intel_plane *intel_plane; |
|
2587 | const struct drm_i915_private *dev_priv = dev->dev_private; |
2309 | struct intel_plane_state *sprstate = NULL; |
2588 | int level, max_level = ilk_wm_max_level(dev); |
2310 | int level, max_level = ilk_wm_max_level(dev); |
2589 | /* LP0 watermark maximums depend on this pipe alone */ |
2311 | /* LP0 watermark maximums depend on this pipe alone */ |
2590 | struct intel_wm_config config = { |
2312 | struct intel_wm_config config = { |
2591 | .num_pipes_active = 1, |
- | |
2592 | .sprites_enabled = params->spr.enabled, |
- | |
2593 | .sprites_scaled = params->spr.scaled, |
2313 | .num_pipes_active = 1, |
2594 | }; |
2314 | }; |
Line -... | Line 2315... | ||
- | 2315 | struct ilk_wm_maximums max; |
|
- | 2316 | ||
- | 2317 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
|
- | 2318 | if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) { |
|
- | 2319 | sprstate = to_intel_plane_state(intel_plane->base.state); |
|
- | 2320 | break; |
|
- | 2321 | } |
|
- | 2322 | } |
|
- | 2323 | ||
- | 2324 | config.sprites_enabled = sprstate->visible; |
|
- | 2325 | config.sprites_scaled = sprstate->visible && |
|
- | 2326 | (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 || |
|
2595 | struct ilk_wm_maximums max; |
2327 | drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); |
2596 | 2328 | ||
2597 | pipe_wm->pipe_enabled = params->active; |
2329 | pipe_wm->pipe_enabled = cstate->base.active; |
Line 2598... | Line 2330... | ||
2598 | pipe_wm->sprites_enabled = params->spr.enabled; |
2330 | pipe_wm->sprites_enabled = sprstate->visible; |
2599 | pipe_wm->sprites_scaled = params->spr.scaled; |
2331 | pipe_wm->sprites_scaled = config.sprites_scaled; |
2600 | 2332 | ||
Line 2601... | Line 2333... | ||
2601 | /* ILK/SNB: LP2+ watermarks only w/o sprites */ |
2333 | /* ILK/SNB: LP2+ watermarks only w/o sprites */ |
2602 | if (INTEL_INFO(dev)->gen <= 6 && params->spr.enabled) |
2334 | if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible) |
2603 | max_level = 1; |
2335 | max_level = 1; |
Line 2604... | Line 2336... | ||
2604 | 2336 | ||
Line 2605... | Line 2337... | ||
2605 | /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ |
2337 | /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ |
2606 | if (params->spr.scaled) |
2338 | if (config.sprites_scaled) |
Line 2607... | Line 2339... | ||
2607 | max_level = 0; |
2339 | max_level = 0; |
Line 2621... | Line 2353... | ||
2621 | ilk_compute_wm_reg_maximums(dev, 1, &max); |
2353 | ilk_compute_wm_reg_maximums(dev, 1, &max); |
Line 2622... | Line 2354... | ||
2622 | 2354 | ||
2623 | for (level = 1; level <= max_level; level++) { |
2355 | for (level = 1; level <= max_level; level++) { |
Line 2624... | Line 2356... | ||
2624 | struct intel_wm_level wm = {}; |
2356 | struct intel_wm_level wm = {}; |
Line 2625... | Line 2357... | ||
2625 | 2357 | ||
2626 | ilk_compute_wm_level(dev_priv, level, params, &wm); |
2358 | ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm); |
2627 | 2359 | ||
2628 | /* |
2360 | /* |
Line 2678... | Line 2410... | ||
2678 | static void ilk_wm_merge(struct drm_device *dev, |
2410 | static void ilk_wm_merge(struct drm_device *dev, |
2679 | const struct intel_wm_config *config, |
2411 | const struct intel_wm_config *config, |
2680 | const struct ilk_wm_maximums *max, |
2412 | const struct ilk_wm_maximums *max, |
2681 | struct intel_pipe_wm *merged) |
2413 | struct intel_pipe_wm *merged) |
2682 | { |
2414 | { |
- | 2415 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
2683 | int level, max_level = ilk_wm_max_level(dev); |
2416 | int level, max_level = ilk_wm_max_level(dev); |
2684 | int last_enabled_level = max_level; |
2417 | int last_enabled_level = max_level; |
Line 2685... | Line 2418... | ||
2685 | 2418 | ||
2686 | /* ILK/SNB/IVB: LP1+ watermarks only w/ single pipe */ |
2419 | /* ILK/SNB/IVB: LP1+ watermarks only w/ single pipe */ |
Line 2718... | Line 2451... | ||
2718 | /* |
2451 | /* |
2719 | * FIXME this is racy. FBC might get enabled later. |
2452 | * FIXME this is racy. FBC might get enabled later. |
2720 | * What we should check here is whether FBC can be |
2453 | * What we should check here is whether FBC can be |
2721 | * enabled sometime later. |
2454 | * enabled sometime later. |
2722 | */ |
2455 | */ |
2723 | if (IS_GEN5(dev) && !merged->fbc_wm_enabled && intel_fbc_enabled(dev)) { |
2456 | if (IS_GEN5(dev) && !merged->fbc_wm_enabled && |
- | 2457 | intel_fbc_enabled(dev_priv)) { |
|
2724 | for (level = 2; level <= max_level; level++) { |
2458 | for (level = 2; level <= max_level; level++) { |
2725 | struct intel_wm_level *wm = &merged->wm[level]; |
2459 | struct intel_wm_level *wm = &merged->wm[level]; |
Line 2726... | Line 2460... | ||
2726 | 2460 | ||
2727 | wm->enable = false; |
2461 | wm->enable = false; |
Line 3022... | Line 2756... | ||
3022 | * On gen9, we need to allocate Display Data Buffer (DDB) portions to the |
2756 | * On gen9, we need to allocate Display Data Buffer (DDB) portions to the |
3023 | * different active planes. |
2757 | * different active planes. |
3024 | */ |
2758 | */ |
Line 3025... | Line 2759... | ||
3025 | 2759 | ||
- | 2760 | #define SKL_DDB_SIZE 896 /* in blocks */ |
|
Line 3026... | Line 2761... | ||
3026 | #define SKL_DDB_SIZE 896 /* in blocks */ |
2761 | #define BXT_DDB_SIZE 512 |
3027 | 2762 | ||
3028 | static void |
2763 | static void |
3029 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, |
2764 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, |
Line 3040... | Line 2775... | ||
3040 | alloc->start = 0; |
2775 | alloc->start = 0; |
3041 | alloc->end = 0; |
2776 | alloc->end = 0; |
3042 | return; |
2777 | return; |
3043 | } |
2778 | } |
Line -... | Line 2779... | ||
- | 2779 | ||
- | 2780 | if (IS_BROXTON(dev)) |
|
- | 2781 | ddb_size = BXT_DDB_SIZE; |
|
3044 | 2782 | else |
|
Line 3045... | Line 2783... | ||
3045 | ddb_size = SKL_DDB_SIZE; |
2783 | ddb_size = SKL_DDB_SIZE; |
Line 3046... | Line 2784... | ||
3046 | 2784 | ||
3047 | ddb_size -= 4; /* 4 blocks for bypass path allocation */ |
2785 | ddb_size -= 4; /* 4 blocks for bypass path allocation */ |
3048 | 2786 | ||
3049 | nth_active_pipe = 0; |
2787 | nth_active_pipe = 0; |
Line 3050... | Line 2788... | ||
3050 | for_each_crtc(dev, crtc) { |
2788 | for_each_crtc(dev, crtc) { |
3051 | if (!intel_crtc_active(crtc)) |
2789 | if (!to_intel_crtc(crtc)->active) |
Line 3079... | Line 2817... | ||
3079 | } |
2817 | } |
Line 3080... | Line 2818... | ||
3080 | 2818 | ||
3081 | void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, |
2819 | void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, |
3082 | struct skl_ddb_allocation *ddb /* out */) |
2820 | struct skl_ddb_allocation *ddb /* out */) |
3083 | { |
- | |
3084 | struct drm_device *dev = dev_priv->dev; |
2821 | { |
3085 | enum pipe pipe; |
2822 | enum pipe pipe; |
3086 | int plane; |
2823 | int plane; |
Line -... | Line 2824... | ||
- | 2824 | u32 val; |
|
- | 2825 | ||
3087 | u32 val; |
2826 | memset(ddb, 0, sizeof(*ddb)); |
- | 2827 | ||
- | 2828 | for_each_pipe(dev_priv, pipe) { |
|
- | 2829 | if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) |
|
3088 | 2830 | continue; |
|
3089 | for_each_pipe(dev_priv, pipe) { |
2831 | |
3090 | for_each_plane(pipe, plane) { |
2832 | for_each_plane(dev_priv, pipe, plane) { |
3091 | val = I915_READ(PLANE_BUF_CFG(pipe, plane)); |
2833 | val = I915_READ(PLANE_BUF_CFG(pipe, plane)); |
3092 | skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane], |
2834 | skl_ddb_entry_init_from_hw(&ddb->plane[pipe][plane], |
Line 3093... | Line 2835... | ||
3093 | val); |
2835 | val); |
3094 | } |
2836 | } |
- | 2837 | ||
3095 | 2838 | val = I915_READ(CUR_BUF_CFG(pipe)); |
|
3096 | val = I915_READ(CUR_BUF_CFG(pipe)); |
2839 | skl_ddb_entry_init_from_hw(&ddb->plane[pipe][PLANE_CURSOR], |
Line 3097... | Line 2840... | ||
3097 | skl_ddb_entry_init_from_hw(&ddb->cursor[pipe], val); |
2840 | val); |
3098 | } |
2841 | } |
3099 | } |
2842 | } |
- | 2843 | ||
- | 2844 | static unsigned int |
|
- | 2845 | skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y) |
|
- | 2846 | { |
|
- | 2847 | ||
- | 2848 | /* for planar format */ |
|
- | 2849 | if (p->y_bytes_per_pixel) { |
|
- | 2850 | if (y) /* y-plane data rate */ |
|
- | 2851 | return p->horiz_pixels * p->vert_pixels * p->y_bytes_per_pixel; |
|
- | 2852 | else /* uv-plane data rate */ |
|
3100 | 2853 | return (p->horiz_pixels/2) * (p->vert_pixels/2) * p->bytes_per_pixel; |
|
3101 | static unsigned int |
2854 | } |
Line 3102... | Line 2855... | ||
3102 | skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p) |
2855 | |
3103 | { |
2856 | /* for packed formats */ |
Line 3121... | Line 2874... | ||
3121 | 2874 | ||
3122 | p = ¶ms->plane[plane]; |
2875 | p = ¶ms->plane[plane]; |
3123 | if (!p->enabled) |
2876 | if (!p->enabled) |
Line -... | Line 2877... | ||
- | 2877 | continue; |
|
- | 2878 | ||
3124 | continue; |
2879 | total_data_rate += skl_plane_relative_data_rate(p, 0); /* packed/uv */ |
- | 2880 | if (p->y_bytes_per_pixel) { |
|
3125 | 2881 | total_data_rate += skl_plane_relative_data_rate(p, 1); /* y-plane */ |
|
Line 3126... | Line 2882... | ||
3126 | total_data_rate += skl_plane_relative_data_rate(p); |
2882 | } |
3127 | } |
2883 | } |
Line 3134... | Line 2890... | ||
3134 | const struct intel_wm_config *config, |
2890 | const struct intel_wm_config *config, |
3135 | const struct skl_pipe_wm_parameters *params, |
2891 | const struct skl_pipe_wm_parameters *params, |
3136 | struct skl_ddb_allocation *ddb /* out */) |
2892 | struct skl_ddb_allocation *ddb /* out */) |
3137 | { |
2893 | { |
3138 | struct drm_device *dev = crtc->dev; |
2894 | struct drm_device *dev = crtc->dev; |
- | 2895 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
3139 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2896 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3140 | enum pipe pipe = intel_crtc->pipe; |
2897 | enum pipe pipe = intel_crtc->pipe; |
3141 | struct skl_ddb_entry *alloc = &ddb->pipe[pipe]; |
2898 | struct skl_ddb_entry *alloc = &ddb->pipe[pipe]; |
3142 | uint16_t alloc_size, start, cursor_blocks; |
2899 | uint16_t alloc_size, start, cursor_blocks; |
- | 2900 | uint16_t minimum[I915_MAX_PLANES]; |
|
- | 2901 | uint16_t y_minimum[I915_MAX_PLANES]; |
|
3143 | unsigned int total_data_rate; |
2902 | unsigned int total_data_rate; |
3144 | int plane; |
2903 | int plane; |
Line 3145... | Line 2904... | ||
3145 | 2904 | ||
3146 | skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc); |
2905 | skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc); |
3147 | alloc_size = skl_ddb_entry_size(alloc); |
2906 | alloc_size = skl_ddb_entry_size(alloc); |
3148 | if (alloc_size == 0) { |
2907 | if (alloc_size == 0) { |
3149 | memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); |
2908 | memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); |
- | 2909 | memset(&ddb->plane[pipe][PLANE_CURSOR], 0, |
|
3150 | memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe])); |
2910 | sizeof(ddb->plane[pipe][PLANE_CURSOR])); |
3151 | return; |
2911 | return; |
Line 3152... | Line 2912... | ||
3152 | } |
2912 | } |
3153 | 2913 | ||
3154 | cursor_blocks = skl_cursor_allocation(config); |
2914 | cursor_blocks = skl_cursor_allocation(config); |
Line 3155... | Line 2915... | ||
3155 | ddb->cursor[pipe].start = alloc->end - cursor_blocks; |
2915 | ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - cursor_blocks; |
3156 | ddb->cursor[pipe].end = alloc->end; |
2916 | ddb->plane[pipe][PLANE_CURSOR].end = alloc->end; |
Line -... | Line 2917... | ||
- | 2917 | ||
- | 2918 | alloc_size -= cursor_blocks; |
|
- | 2919 | alloc->end -= cursor_blocks; |
|
- | 2920 | ||
- | 2921 | /* 1. Allocate the mininum required blocks for each active plane */ |
|
- | 2922 | for_each_plane(dev_priv, pipe, plane) { |
|
- | 2923 | const struct intel_plane_wm_parameters *p; |
|
- | 2924 | ||
- | 2925 | p = ¶ms->plane[plane]; |
|
- | 2926 | if (!p->enabled) |
|
- | 2927 | continue; |
|
- | 2928 | ||
- | 2929 | minimum[plane] = 8; |
|
- | 2930 | alloc_size -= minimum[plane]; |
|
3157 | 2931 | y_minimum[plane] = p->y_bytes_per_pixel ? 8 : 0; |
|
3158 | alloc_size -= cursor_blocks; |
2932 | alloc_size -= y_minimum[plane]; |
3159 | alloc->end -= cursor_blocks; |
2933 | } |
3160 | 2934 | ||
3161 | /* |
2935 | /* |
3162 | * Each active plane get a portion of the remaining space, in |
2936 | * 2. Distribute the remaining space in proportion to the amount of |
3163 | * proportion to the amount of data they need to fetch from memory. |
2937 | * data each plane needs to fetch from memory. |
Line 3164... | Line 2938... | ||
3164 | * |
2938 | * |
3165 | * FIXME: we may not allocate every single block here. |
2939 | * FIXME: we may not allocate every single block here. |
3166 | */ |
2940 | */ |
3167 | total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params); |
2941 | total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params); |
3168 | 2942 | ||
Line 3169... | Line 2943... | ||
3169 | start = alloc->start; |
2943 | start = alloc->start; |
3170 | for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { |
2944 | for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { |
3171 | const struct intel_plane_wm_parameters *p; |
2945 | const struct intel_plane_wm_parameters *p; |
Line 3172... | Line 2946... | ||
3172 | unsigned int data_rate; |
2946 | unsigned int data_rate, y_data_rate; |
Line 3173... | Line 2947... | ||
3173 | uint16_t plane_blocks; |
2947 | uint16_t plane_blocks, y_plane_blocks = 0; |
- | 2948 | ||
3174 | 2949 | p = ¶ms->plane[plane]; |
|
3175 | p = ¶ms->plane[plane]; |
2950 | if (!p->enabled) |
3176 | if (!p->enabled) |
2951 | continue; |
- | 2952 | ||
3177 | continue; |
2953 | data_rate = skl_plane_relative_data_rate(p, 0); |
3178 | 2954 | ||
Line 3179... | Line 2955... | ||
3179 | data_rate = skl_plane_relative_data_rate(p); |
2955 | /* |
3180 | 2956 | * allocation for (packed formats) or (uv-plane part of planar format): |
|
Line 3181... | Line 2957... | ||
3181 | /* |
2957 | * promote the expression to 64 bits to avoid overflowing, the |
- | 2958 | * result is < available as data_rate / total_data_rate < 1 |
|
- | 2959 | */ |
|
- | 2960 | plane_blocks = minimum[plane]; |
|
- | 2961 | plane_blocks += div_u64((uint64_t)alloc_size * data_rate, |
|
- | 2962 | total_data_rate); |
|
- | 2963 | ||
- | 2964 | ddb->plane[pipe][plane].start = start; |
|
- | 2965 | ddb->plane[pipe][plane].end = start + plane_blocks; |
|
- | 2966 | ||
- | 2967 | start += plane_blocks; |
|
- | 2968 | ||
- | 2969 | /* |
|
- | 2970 | * allocation for y_plane part of planar format: |
|
- | 2971 | */ |
|
3182 | * promote the expression to 64 bits to avoid overflowing, the |
2972 | if (p->y_bytes_per_pixel) { |
Line 3183... | Line 2973... | ||
3183 | * result is < available as data_rate / total_data_rate < 1 |
2973 | y_data_rate = skl_plane_relative_data_rate(p, 1); |
Line -... | Line 2974... | ||
- | 2974 | y_plane_blocks = y_minimum[plane]; |
|
- | 2975 | y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate, |
|
3184 | */ |
2976 | total_data_rate); |
3185 | plane_blocks = div_u64((uint64_t)alloc_size * data_rate, |
2977 | |
3186 | total_data_rate); |
2978 | ddb->y_plane[pipe][plane].start = start; |
3187 | 2979 | ddb->y_plane[pipe][plane].end = start + y_plane_blocks; |
|
3188 | ddb->plane[pipe][plane].start = start; |
2980 | |
Line 3189... | Line 2981... | ||
3189 | ddb->plane[pipe][plane].end = start + plane_blocks; |
2981 | start += y_plane_blocks; |
3190 | 2982 | } |
|
3191 | start += plane_blocks; |
2983 | |
Line 3211... | Line 3003... | ||
3211 | uint32_t wm_intermediate_val, ret; |
3003 | uint32_t wm_intermediate_val, ret; |
Line 3212... | Line 3004... | ||
3212 | 3004 | ||
3213 | if (latency == 0) |
3005 | if (latency == 0) |
Line 3214... | Line 3006... | ||
3214 | return UINT_MAX; |
3006 | return UINT_MAX; |
3215 | 3007 | ||
Line 3216... | Line 3008... | ||
3216 | wm_intermediate_val = latency * pixel_rate * bytes_per_pixel; |
3008 | wm_intermediate_val = latency * pixel_rate * bytes_per_pixel / 512; |
3217 | ret = DIV_ROUND_UP(wm_intermediate_val, 1000); |
3009 | ret = DIV_ROUND_UP(wm_intermediate_val, 1000); |
Line 3218... | Line 3010... | ||
3218 | 3010 | ||
3219 | return ret; |
3011 | return ret; |
3220 | } |
3012 | } |
3221 | 3013 | ||
- | 3014 | static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, |
|
3222 | static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, |
3015 | uint32_t horiz_pixels, uint8_t bytes_per_pixel, |
- | 3016 | uint64_t tiling, uint32_t latency) |
|
Line 3223... | Line 3017... | ||
3223 | uint32_t horiz_pixels, uint8_t bytes_per_pixel, |
3017 | { |
3224 | uint32_t latency) |
3018 | uint32_t ret; |
Line 3225... | Line 3019... | ||
3225 | { |
3019 | uint32_t plane_bytes_per_line, plane_blocks_per_line; |
- | 3020 | uint32_t wm_intermediate_val; |
|
- | 3021 | ||
- | 3022 | if (latency == 0) |
|
- | 3023 | return UINT_MAX; |
|
- | 3024 | ||
- | 3025 | plane_bytes_per_line = horiz_pixels * bytes_per_pixel; |
|
- | 3026 | ||
- | 3027 | if (tiling == I915_FORMAT_MOD_Y_TILED || |
|
- | 3028 | tiling == I915_FORMAT_MOD_Yf_TILED) { |
|
- | 3029 | plane_bytes_per_line *= 4; |
|
3226 | uint32_t ret, plane_bytes_per_line, wm_intermediate_val; |
3030 | plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); |
3227 | 3031 | plane_blocks_per_line /= 4; |
|
3228 | if (latency == 0) |
3032 | } else { |
Line 3229... | Line 3033... | ||
3229 | return UINT_MAX; |
3033 | plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); |
3230 | 3034 | } |
|
Line 3231... | Line 3035... | ||
3231 | plane_bytes_per_line = horiz_pixels * bytes_per_pixel; |
3035 | |
Line 3246... | Line 3050... | ||
3246 | 3050 | ||
3247 | if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe], |
3051 | if (memcmp(new_ddb->plane[pipe], cur_ddb->plane[pipe], |
3248 | sizeof(new_ddb->plane[pipe]))) |
3052 | sizeof(new_ddb->plane[pipe]))) |
Line 3249... | Line 3053... | ||
3249 | return true; |
3053 | return true; |
3250 | 3054 | ||
3251 | if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe], |
3055 | if (memcmp(&new_ddb->plane[pipe][PLANE_CURSOR], &cur_ddb->plane[pipe][PLANE_CURSOR], |
Line 3252... | Line 3056... | ||
3252 | sizeof(new_ddb->cursor[pipe]))) |
3056 | sizeof(new_ddb->plane[pipe][PLANE_CURSOR]))) |
3253 | return true; |
3057 | return true; |
Line 3260... | Line 3064... | ||
3260 | { |
3064 | { |
3261 | struct drm_crtc *crtc; |
3065 | struct drm_crtc *crtc; |
3262 | struct drm_plane *plane; |
3066 | struct drm_plane *plane; |
Line 3263... | Line 3067... | ||
3263 | 3067 | ||
3264 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
3068 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
Line 3265... | Line 3069... | ||
3265 | config->num_pipes_active += intel_crtc_active(crtc); |
3069 | config->num_pipes_active += to_intel_crtc(crtc)->active; |
3266 | 3070 | ||
3267 | /* FIXME: I don't think we need those two global parameters on SKL */ |
3071 | /* FIXME: I don't think we need those two global parameters on SKL */ |
Line 3278... | Line 3082... | ||
3278 | { |
3082 | { |
3279 | struct drm_device *dev = crtc->dev; |
3083 | struct drm_device *dev = crtc->dev; |
3280 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3084 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3281 | enum pipe pipe = intel_crtc->pipe; |
3085 | enum pipe pipe = intel_crtc->pipe; |
3282 | struct drm_plane *plane; |
3086 | struct drm_plane *plane; |
- | 3087 | struct drm_framebuffer *fb; |
|
3283 | int i = 1; /* Index for sprite planes start */ |
3088 | int i = 1; /* Index for sprite planes start */ |
Line 3284... | Line 3089... | ||
3284 | 3089 | ||
3285 | p->active = intel_crtc_active(crtc); |
3090 | p->active = intel_crtc->active; |
3286 | if (p->active) { |
3091 | if (p->active) { |
3287 | p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal; |
3092 | p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal; |
Line 3288... | Line 3093... | ||
3288 | p->pixel_rate = skl_pipe_pixel_rate(&intel_crtc->config); |
3093 | p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config); |
3289 | 3094 | ||
3290 | /* |
3095 | fb = crtc->primary->state->fb; |
3291 | * For now, assume primary and cursor planes are always enabled. |
3096 | /* For planar: Bpp is for uv plane, y_Bpp is for y plane */ |
- | 3097 | if (fb) { |
|
- | 3098 | p->plane[0].enabled = true; |
|
- | 3099 | p->plane[0].bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ? |
|
- | 3100 | drm_format_plane_cpp(fb->pixel_format, 1) : |
|
- | 3101 | drm_format_plane_cpp(fb->pixel_format, 0); |
|
- | 3102 | p->plane[0].y_bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ? |
|
- | 3103 | drm_format_plane_cpp(fb->pixel_format, 0) : 0; |
|
- | 3104 | p->plane[0].tiling = fb->modifier[0]; |
|
3292 | */ |
3105 | } else { |
3293 | p->plane[0].enabled = true; |
3106 | p->plane[0].enabled = false; |
- | 3107 | p->plane[0].bytes_per_pixel = 0; |
|
- | 3108 | p->plane[0].y_bytes_per_pixel = 0; |
|
3294 | p->plane[0].bytes_per_pixel = |
3109 | p->plane[0].tiling = DRM_FORMAT_MOD_NONE; |
3295 | crtc->primary->fb->bits_per_pixel / 8; |
3110 | } |
- | 3111 | p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w; |
|
3296 | p->plane[0].horiz_pixels = intel_crtc->config.pipe_src_w; |
3112 | p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h; |
3297 | p->plane[0].vert_pixels = intel_crtc->config.pipe_src_h; |
3113 | p->plane[0].rotation = crtc->primary->state->rotation; |
3298 | 3114 | ||
- | 3115 | fb = crtc->cursor->state->fb; |
|
- | 3116 | p->plane[PLANE_CURSOR].y_bytes_per_pixel = 0; |
|
- | 3117 | if (fb) { |
|
3299 | p->cursor.enabled = true; |
3118 | p->plane[PLANE_CURSOR].enabled = true; |
- | 3119 | p->plane[PLANE_CURSOR].bytes_per_pixel = fb->bits_per_pixel / 8; |
|
- | 3120 | p->plane[PLANE_CURSOR].horiz_pixels = crtc->cursor->state->crtc_w; |
|
- | 3121 | p->plane[PLANE_CURSOR].vert_pixels = crtc->cursor->state->crtc_h; |
|
- | 3122 | } else { |
|
3300 | p->cursor.bytes_per_pixel = 4; |
3123 | p->plane[PLANE_CURSOR].enabled = false; |
- | 3124 | p->plane[PLANE_CURSOR].bytes_per_pixel = 0; |
|
- | 3125 | p->plane[PLANE_CURSOR].horiz_pixels = 64; |
|
3301 | p->cursor.horiz_pixels = intel_crtc->cursor_width ? |
3126 | p->plane[PLANE_CURSOR].vert_pixels = 64; |
Line 3302... | Line 3127... | ||
3302 | intel_crtc->cursor_width : 64; |
3127 | } |
3303 | } |
3128 | } |
Line 3304... | Line 3129... | ||
3304 | 3129 | ||
- | 3130 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { |
|
3305 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { |
3131 | struct intel_plane *intel_plane = to_intel_plane(plane); |
3306 | struct intel_plane *intel_plane = to_intel_plane(plane); |
3132 | |
3307 | 3133 | if (intel_plane->pipe == pipe && |
|
Line 3308... | Line 3134... | ||
3308 | if (intel_plane->pipe == pipe) |
3134 | plane->type == DRM_PLANE_TYPE_OVERLAY) |
- | 3135 | p->plane[i++] = intel_plane->wm; |
|
3309 | p->plane[i++] = intel_plane->wm; |
3136 | } |
3310 | } |
3137 | } |
3311 | } |
3138 | |
3312 | 3139 | static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, |
|
3313 | static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p, |
3140 | struct skl_pipe_wm_parameters *p, |
3314 | struct intel_plane_wm_parameters *p_params, |
3141 | struct intel_plane_wm_parameters *p_params, |
- | 3142 | uint16_t ddb_allocation, |
|
- | 3143 | int level, |
|
3315 | uint16_t ddb_allocation, |
3144 | uint16_t *out_blocks, /* out */ |
- | 3145 | uint8_t *out_lines /* out */) |
|
3316 | uint32_t mem_value, |
3146 | { |
- | 3147 | uint32_t latency = dev_priv->wm.skl_latency[level]; |
|
Line 3317... | Line 3148... | ||
3317 | uint16_t *out_blocks, /* out */ |
3148 | uint32_t method1, method2; |
3318 | uint8_t *out_lines /* out */) |
3149 | uint32_t plane_bytes_per_line, plane_blocks_per_line; |
Line -... | Line 3150... | ||
- | 3150 | uint32_t res_blocks, res_lines; |
|
- | 3151 | uint32_t selected_result; |
|
- | 3152 | uint8_t bytes_per_pixel; |
|
3319 | { |
3153 | |
3320 | uint32_t method1, method2, plane_bytes_per_line, res_blocks, res_lines; |
3154 | if (latency == 0 || !p->active || !p_params->enabled) |
3321 | uint32_t result_bytes; |
3155 | return false; |
3322 | 3156 | ||
3323 | if (mem_value == 0 || !p->active || !p_params->enabled) |
3157 | bytes_per_pixel = p_params->y_bytes_per_pixel ? |
3324 | return false; |
3158 | p_params->y_bytes_per_pixel : |
- | 3159 | p_params->bytes_per_pixel; |
|
- | 3160 | method1 = skl_wm_method1(p->pixel_rate, |
|
- | 3161 | bytes_per_pixel, |
|
- | 3162 | latency); |
|
- | 3163 | method2 = skl_wm_method2(p->pixel_rate, |
|
- | 3164 | p->pipe_htotal, |
|
- | 3165 | p_params->horiz_pixels, |
|
- | 3166 | bytes_per_pixel, |
|
- | 3167 | p_params->tiling, |
|
- | 3168 | latency); |
|
- | 3169 | ||
- | 3170 | plane_bytes_per_line = p_params->horiz_pixels * bytes_per_pixel; |
|
3325 | 3171 | plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); |
|
- | 3172 | ||
- | 3173 | if (p_params->tiling == I915_FORMAT_MOD_Y_TILED || |
|
3326 | method1 = skl_wm_method1(p->pixel_rate, |
3174 | p_params->tiling == I915_FORMAT_MOD_Yf_TILED) { |
- | 3175 | uint32_t min_scanlines = 4; |
|
- | 3176 | uint32_t y_tile_minimum; |
|
- | 3177 | if (intel_rotation_90_or_270(p_params->rotation)) { |
|
- | 3178 | switch (p_params->bytes_per_pixel) { |
|
- | 3179 | case 1: |
|
- | 3180 | min_scanlines = 16; |
|
- | 3181 | break; |
|
- | 3182 | case 2: |
|
- | 3183 | min_scanlines = 8; |
|
- | 3184 | break; |
|
- | 3185 | case 8: |
|
- | 3186 | WARN(1, "Unsupported pixel depth for rotation"); |
|
- | 3187 | } |
|
- | 3188 | } |
|
- | 3189 | y_tile_minimum = plane_blocks_per_line * min_scanlines; |
|
Line 3327... | Line 3190... | ||
3327 | p_params->bytes_per_pixel, |
3190 | selected_result = max(method2, y_tile_minimum); |
3328 | mem_value); |
3191 | } else { |
Line 3329... | Line 3192... | ||
3329 | method2 = skl_wm_method2(p->pixel_rate, |
3192 | if ((ddb_allocation / plane_blocks_per_line) >= 1) |
3330 | p->pipe_htotal, |
3193 | selected_result = min(method1, method2); |
3331 | p_params->horiz_pixels, |
3194 | else |
- | 3195 | selected_result = method1; |
|
3332 | p_params->bytes_per_pixel, |
3196 | } |
3333 | mem_value); |
3197 | |
3334 | 3198 | res_blocks = selected_result + 1; |
|
3335 | plane_bytes_per_line = p_params->horiz_pixels * |
- | |
3336 | p_params->bytes_per_pixel; |
- | |
Line 3337... | Line 3199... | ||
3337 | 3199 | res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line); |
|
3338 | /* For now xtile and linear */ |
3200 | |
Line 3339... | Line 3201... | ||
3339 | if (((ddb_allocation * 512) / plane_bytes_per_line) >= 1) |
3201 | if (level >= 1 && level <= 7) { |
3340 | result_bytes = min(method1, method2); |
3202 | if (p_params->tiling == I915_FORMAT_MOD_Y_TILED || |
Line 3359... | Line 3221... | ||
3359 | enum pipe pipe, |
3221 | enum pipe pipe, |
3360 | int level, |
3222 | int level, |
3361 | int num_planes, |
3223 | int num_planes, |
3362 | struct skl_wm_level *result) |
3224 | struct skl_wm_level *result) |
3363 | { |
3225 | { |
3364 | uint16_t latency = dev_priv->wm.skl_latency[level]; |
- | |
3365 | uint16_t ddb_blocks; |
3226 | uint16_t ddb_blocks; |
3366 | int i; |
3227 | int i; |
Line 3367... | Line 3228... | ||
3367 | 3228 | ||
3368 | for (i = 0; i < num_planes; i++) { |
3229 | for (i = 0; i < num_planes; i++) { |
Line 3369... | Line 3230... | ||
3369 | ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); |
3230 | ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); |
- | 3231 | ||
3370 | 3232 | result->plane_en[i] = skl_compute_plane_wm(dev_priv, |
|
3371 | result->plane_en[i] = skl_compute_plane_wm(p, &p->plane[i], |
3233 | p, &p->plane[i], |
3372 | ddb_blocks, |
3234 | ddb_blocks, |
3373 | latency, |
3235 | level, |
3374 | &result->plane_res_b[i], |
3236 | &result->plane_res_b[i], |
Line 3375... | Line 3237... | ||
3375 | &result->plane_res_l[i]); |
3237 | &result->plane_res_l[i]); |
3376 | } |
3238 | } |
- | 3239 | ||
- | 3240 | ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][PLANE_CURSOR]); |
|
3377 | 3241 | result->plane_en[PLANE_CURSOR] = skl_compute_plane_wm(dev_priv, p, |
|
3378 | ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]); |
3242 | &p->plane[PLANE_CURSOR], |
3379 | result->cursor_en = skl_compute_plane_wm(p, &p->cursor, ddb_blocks, |
3243 | ddb_blocks, level, |
Line 3380... | Line 3244... | ||
3380 | latency, &result->cursor_res_b, |
3244 | &result->plane_res_b[PLANE_CURSOR], |
3381 | &result->cursor_res_l); |
3245 | &result->plane_res_l[PLANE_CURSOR]); |
3382 | } |
3246 | } |
3383 | 3247 | ||
3384 | static uint32_t |
3248 | static uint32_t |
Line 3385... | Line 3249... | ||
3385 | skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p) |
3249 | skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p) |
- | 3250 | { |
|
Line -... | Line 3251... | ||
- | 3251 | if (!to_intel_crtc(crtc)->active) |
|
3386 | { |
3252 | return 0; |
Line 3387... | Line 3253... | ||
3387 | if (!intel_crtc_active(crtc)) |
3253 | |
3388 | return 0; |
3254 | if (WARN_ON(p->pixel_rate == 0)) |
3389 | 3255 | return 0; |
|
Line 3402... | Line 3268... | ||
3402 | return; |
3268 | return; |
Line 3403... | Line 3269... | ||
3403 | 3269 | ||
3404 | /* Until we know more, just disable transition WMs */ |
3270 | /* Until we know more, just disable transition WMs */ |
3405 | for (i = 0; i < intel_num_planes(intel_crtc); i++) |
3271 | for (i = 0; i < intel_num_planes(intel_crtc); i++) |
3406 | trans_wm->plane_en[i] = false; |
3272 | trans_wm->plane_en[i] = false; |
3407 | trans_wm->cursor_en = false; |
3273 | trans_wm->plane_en[PLANE_CURSOR] = false; |
Line 3408... | Line 3274... | ||
3408 | } |
3274 | } |
3409 | 3275 | ||
3410 | static void skl_compute_pipe_wm(struct drm_crtc *crtc, |
3276 | static void skl_compute_pipe_wm(struct drm_crtc *crtc, |
Line 3451... | Line 3317... | ||
3451 | r->plane[pipe][i][level] = temp; |
3317 | r->plane[pipe][i][level] = temp; |
3452 | } |
3318 | } |
Line 3453... | Line 3319... | ||
3453 | 3319 | ||
Line 3454... | Line 3320... | ||
3454 | temp = 0; |
3320 | temp = 0; |
3455 | 3321 | ||
Line 3456... | Line 3322... | ||
3456 | temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT; |
3322 | temp |= p_wm->wm[level].plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT; |
3457 | temp |= p_wm->wm[level].cursor_res_b; |
3323 | temp |= p_wm->wm[level].plane_res_b[PLANE_CURSOR]; |
Line 3458... | Line 3324... | ||
3458 | 3324 | ||
Line 3459... | Line 3325... | ||
3459 | if (p_wm->wm[level].cursor_en) |
3325 | if (p_wm->wm[level].plane_en[PLANE_CURSOR]) |
Line 3460... | Line 3326... | ||
3460 | temp |= PLANE_WM_EN; |
3326 | temp |= PLANE_WM_EN; |
3461 | 3327 | ||
Line 3473... | Line 3339... | ||
3473 | 3339 | ||
3474 | r->plane_trans[pipe][i] = temp; |
3340 | r->plane_trans[pipe][i] = temp; |
Line 3475... | Line 3341... | ||
3475 | } |
3341 | } |
3476 | 3342 | ||
3477 | temp = 0; |
3343 | temp = 0; |
3478 | temp |= p_wm->trans_wm.cursor_res_l << PLANE_WM_LINES_SHIFT; |
3344 | temp |= p_wm->trans_wm.plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT; |
3479 | temp |= p_wm->trans_wm.cursor_res_b; |
3345 | temp |= p_wm->trans_wm.plane_res_b[PLANE_CURSOR]; |
Line 3480... | Line 3346... | ||
3480 | if (p_wm->trans_wm.cursor_en) |
3346 | if (p_wm->trans_wm.plane_en[PLANE_CURSOR]) |
Line 3481... | Line 3347... | ||
3481 | temp |= PLANE_WM_EN; |
3347 | temp |= PLANE_WM_EN; |
3482 | 3348 | ||
Line 3483... | Line 3349... | ||
3483 | r->cursor_trans[pipe] = temp; |
3349 | r->plane_trans[pipe][PLANE_CURSOR] = temp; |
Line 3512... | Line 3378... | ||
3512 | for (level = 0; level <= max_level; level++) { |
3378 | for (level = 0; level <= max_level; level++) { |
3513 | for (i = 0; i < intel_num_planes(crtc); i++) |
3379 | for (i = 0; i < intel_num_planes(crtc); i++) |
3514 | I915_WRITE(PLANE_WM(pipe, i, level), |
3380 | I915_WRITE(PLANE_WM(pipe, i, level), |
3515 | new->plane[pipe][i][level]); |
3381 | new->plane[pipe][i][level]); |
3516 | I915_WRITE(CUR_WM(pipe, level), |
3382 | I915_WRITE(CUR_WM(pipe, level), |
3517 | new->cursor[pipe][level]); |
3383 | new->plane[pipe][PLANE_CURSOR][level]); |
3518 | } |
3384 | } |
3519 | for (i = 0; i < intel_num_planes(crtc); i++) |
3385 | for (i = 0; i < intel_num_planes(crtc); i++) |
3520 | I915_WRITE(PLANE_WM_TRANS(pipe, i), |
3386 | I915_WRITE(PLANE_WM_TRANS(pipe, i), |
3521 | new->plane_trans[pipe][i]); |
3387 | new->plane_trans[pipe][i]); |
3522 | I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]); |
3388 | I915_WRITE(CUR_WM_TRANS(pipe), |
- | 3389 | new->plane_trans[pipe][PLANE_CURSOR]); |
|
Line 3523... | Line 3390... | ||
3523 | 3390 | ||
3524 | for (i = 0; i < intel_num_planes(crtc); i++) |
3391 | for (i = 0; i < intel_num_planes(crtc); i++) { |
3525 | skl_ddb_entry_write(dev_priv, |
3392 | skl_ddb_entry_write(dev_priv, |
3526 | PLANE_BUF_CFG(pipe, i), |
3393 | PLANE_BUF_CFG(pipe, i), |
- | 3394 | &new->ddb.plane[pipe][i]); |
|
- | 3395 | skl_ddb_entry_write(dev_priv, |
|
- | 3396 | PLANE_NV12_BUF_CFG(pipe, i), |
|
- | 3397 | &new->ddb.y_plane[pipe][i]); |
|
Line 3527... | Line 3398... | ||
3527 | &new->ddb.plane[pipe][i]); |
3398 | } |
3528 | 3399 | ||
3529 | skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), |
3400 | skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), |
3530 | &new->ddb.cursor[pipe]); |
3401 | &new->ddb.plane[pipe][PLANE_CURSOR]); |
Line 3531... | Line 3402... | ||
3531 | } |
3402 | } |
3532 | } |
3403 | } |
Line 3556... | Line 3427... | ||
3556 | */ |
3427 | */ |
Line 3557... | Line 3428... | ||
3557 | 3428 | ||
3558 | static void |
3429 | static void |
3559 | skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, int pass) |
3430 | skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, int pass) |
3560 | { |
- | |
3561 | struct drm_device *dev = dev_priv->dev; |
3431 | { |
Line 3562... | Line 3432... | ||
3562 | int plane; |
3432 | int plane; |
Line 3563... | Line 3433... | ||
3563 | 3433 | ||
3564 | DRM_DEBUG_KMS("flush pipe %c (pass %d)\n", pipe_name(pipe), pass); |
3434 | DRM_DEBUG_KMS("flush pipe %c (pass %d)\n", pipe_name(pipe), pass); |
3565 | 3435 | ||
3566 | for_each_plane(pipe, plane) { |
3436 | for_each_plane(dev_priv, pipe, plane) { |
3567 | I915_WRITE(PLANE_SURF(pipe, plane), |
3437 | I915_WRITE(PLANE_SURF(pipe, plane), |
3568 | I915_READ(PLANE_SURF(pipe, plane))); |
3438 | I915_READ(PLANE_SURF(pipe, plane))); |
Line 3588... | Line 3458... | ||
3588 | static void skl_flush_wm_values(struct drm_i915_private *dev_priv, |
3458 | static void skl_flush_wm_values(struct drm_i915_private *dev_priv, |
3589 | struct skl_wm_values *new_values) |
3459 | struct skl_wm_values *new_values) |
3590 | { |
3460 | { |
3591 | struct drm_device *dev = dev_priv->dev; |
3461 | struct drm_device *dev = dev_priv->dev; |
3592 | struct skl_ddb_allocation *cur_ddb, *new_ddb; |
3462 | struct skl_ddb_allocation *cur_ddb, *new_ddb; |
3593 | bool reallocated[I915_MAX_PIPES] = {false, false, false}; |
3463 | bool reallocated[I915_MAX_PIPES] = {}; |
3594 | struct intel_crtc *crtc; |
3464 | struct intel_crtc *crtc; |
3595 | enum pipe pipe; |
3465 | enum pipe pipe; |
Line 3596... | Line 3466... | ||
3596 | 3466 | ||
3597 | new_ddb = &new_values->ddb; |
3467 | new_ddb = &new_values->ddb; |
Line 3638... | Line 3508... | ||
3638 | 3508 | ||
3639 | if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) < |
3509 | if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) < |
3640 | skl_ddb_entry_size(&cur_ddb->pipe[pipe])) { |
3510 | skl_ddb_entry_size(&cur_ddb->pipe[pipe])) { |
3641 | skl_wm_flush_pipe(dev_priv, pipe, 2); |
3511 | skl_wm_flush_pipe(dev_priv, pipe, 2); |
3642 | intel_wait_for_vblank(dev, pipe); |
- | |
3643 | } |
- | |
3644 | 3512 | intel_wait_for_vblank(dev, pipe); |
|
3645 | reallocated[pipe] = true; |
3513 | reallocated[pipe] = true; |
- | 3514 | } |
|
Line 3646... | Line 3515... | ||
3646 | } |
3515 | } |
3647 | 3516 | ||
3648 | /* |
3517 | /* |
3649 | * Third pass: flush the pipes that got more space allocated. |
3518 | * Third pass: flush the pipes that got more space allocated. |
Line 3682... | Line 3551... | ||
3682 | 3551 | ||
3683 | if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm))) |
3552 | if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm))) |
Line 3684... | Line 3553... | ||
3684 | return false; |
3553 | return false; |
- | 3554 | ||
3685 | 3555 | intel_crtc->wm.skl_active = *pipe_wm; |
|
3686 | intel_crtc->wm.skl_active = *pipe_wm; |
3556 | |
Line 3687... | Line 3557... | ||
3687 | return true; |
3557 | return true; |
3688 | } |
3558 | } |
Line 3734... | Line 3604... | ||
3734 | skl_compute_wm_results(dev, ¶ms, &pipe_wm, r, intel_crtc); |
3604 | skl_compute_wm_results(dev, ¶ms, &pipe_wm, r, intel_crtc); |
3735 | r->dirty[intel_crtc->pipe] = true; |
3605 | r->dirty[intel_crtc->pipe] = true; |
3736 | } |
3606 | } |
3737 | } |
3607 | } |
Line -... | Line 3608... | ||
- | 3608 | ||
- | 3609 | static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe) |
|
- | 3610 | { |
|
- | 3611 | watermarks->wm_linetime[pipe] = 0; |
|
- | 3612 | memset(watermarks->plane[pipe], 0, |
|
- | 3613 | sizeof(uint32_t) * 8 * I915_MAX_PLANES); |
|
- | 3614 | memset(watermarks->plane_trans[pipe], |
|
- | 3615 | 0, sizeof(uint32_t) * I915_MAX_PLANES); |
|
- | 3616 | watermarks->plane_trans[pipe][PLANE_CURSOR] = 0; |
|
- | 3617 | ||
- | 3618 | /* Clear ddb entries for pipe */ |
|
- | 3619 | memset(&watermarks->ddb.pipe[pipe], 0, sizeof(struct skl_ddb_entry)); |
|
- | 3620 | memset(&watermarks->ddb.plane[pipe], 0, |
|
- | 3621 | sizeof(struct skl_ddb_entry) * I915_MAX_PLANES); |
|
- | 3622 | memset(&watermarks->ddb.y_plane[pipe], 0, |
|
- | 3623 | sizeof(struct skl_ddb_entry) * I915_MAX_PLANES); |
|
- | 3624 | memset(&watermarks->ddb.plane[pipe][PLANE_CURSOR], 0, |
|
- | 3625 | sizeof(struct skl_ddb_entry)); |
|
- | 3626 | ||
- | 3627 | } |
|
3738 | 3628 | ||
3739 | static void skl_update_wm(struct drm_crtc *crtc) |
3629 | static void skl_update_wm(struct drm_crtc *crtc) |
3740 | { |
3630 | { |
3741 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3631 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3742 | struct drm_device *dev = crtc->dev; |
3632 | struct drm_device *dev = crtc->dev; |
3743 | struct drm_i915_private *dev_priv = dev->dev_private; |
3633 | struct drm_i915_private *dev_priv = dev->dev_private; |
3744 | struct skl_pipe_wm_parameters params = {}; |
3634 | struct skl_pipe_wm_parameters params = {}; |
3745 | struct skl_wm_values *results = &dev_priv->wm.skl_results; |
3635 | struct skl_wm_values *results = &dev_priv->wm.skl_results; |
3746 | struct skl_pipe_wm pipe_wm = {}; |
3636 | struct skl_pipe_wm pipe_wm = {}; |
Line -... | Line 3637... | ||
- | 3637 | struct intel_wm_config config = {}; |
|
- | 3638 | ||
3747 | struct intel_wm_config config = {}; |
3639 | |
- | 3640 | /* Clear all dirty flags */ |
|
- | 3641 | memset(results->dirty, 0, sizeof(bool) * I915_MAX_PIPES); |
|
Line 3748... | Line 3642... | ||
3748 | 3642 | ||
Line 3749... | Line 3643... | ||
3749 | memset(results, 0, sizeof(*results)); |
3643 | skl_clear_wm(results, intel_crtc->pipe); |
3750 | 3644 | ||
Line 3769... | Line 3663... | ||
3769 | skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc, |
3663 | skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc, |
3770 | uint32_t sprite_width, uint32_t sprite_height, |
3664 | uint32_t sprite_width, uint32_t sprite_height, |
3771 | int pixel_size, bool enabled, bool scaled) |
3665 | int pixel_size, bool enabled, bool scaled) |
3772 | { |
3666 | { |
3773 | struct intel_plane *intel_plane = to_intel_plane(plane); |
3667 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | 3668 | struct drm_framebuffer *fb = plane->state->fb; |
|
Line 3774... | Line 3669... | ||
3774 | 3669 | ||
3775 | intel_plane->wm.enabled = enabled; |
3670 | intel_plane->wm.enabled = enabled; |
3776 | intel_plane->wm.scaled = scaled; |
3671 | intel_plane->wm.scaled = scaled; |
3777 | intel_plane->wm.horiz_pixels = sprite_width; |
3672 | intel_plane->wm.horiz_pixels = sprite_width; |
- | 3673 | intel_plane->wm.vert_pixels = sprite_height; |
|
- | 3674 | intel_plane->wm.tiling = DRM_FORMAT_MOD_NONE; |
|
- | 3675 | ||
3778 | intel_plane->wm.vert_pixels = sprite_height; |
3676 | /* For planar: Bpp is for UV plane, y_Bpp is for Y plane */ |
- | 3677 | intel_plane->wm.bytes_per_pixel = |
|
- | 3678 | (fb && fb->pixel_format == DRM_FORMAT_NV12) ? |
|
- | 3679 | drm_format_plane_cpp(plane->state->fb->pixel_format, 1) : pixel_size; |
|
- | 3680 | intel_plane->wm.y_bytes_per_pixel = |
|
- | 3681 | (fb && fb->pixel_format == DRM_FORMAT_NV12) ? |
|
- | 3682 | drm_format_plane_cpp(plane->state->fb->pixel_format, 0) : 0; |
|
- | 3683 | ||
- | 3684 | /* |
|
- | 3685 | * Framebuffer can be NULL on plane disable, but it does not |
|
- | 3686 | * matter for watermarks if we assume no tiling in that case. |
|
- | 3687 | */ |
|
- | 3688 | if (fb) |
|
- | 3689 | intel_plane->wm.tiling = fb->modifier[0]; |
|
Line 3779... | Line 3690... | ||
3779 | intel_plane->wm.bytes_per_pixel = pixel_size; |
3690 | intel_plane->wm.rotation = plane->state->rotation; |
3780 | 3691 | ||
Line 3781... | Line 3692... | ||
3781 | skl_update_wm(crtc); |
3692 | skl_update_wm(crtc); |
3782 | } |
3693 | } |
3783 | 3694 | ||
- | 3695 | static void ilk_update_wm(struct drm_crtc *crtc) |
|
3784 | static void ilk_update_wm(struct drm_crtc *crtc) |
3696 | { |
3785 | { |
3697 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3786 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3698 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
3787 | struct drm_device *dev = crtc->dev; |
- | |
3788 | struct drm_i915_private *dev_priv = dev->dev_private; |
3699 | struct drm_device *dev = crtc->dev; |
3789 | struct ilk_wm_maximums max; |
3700 | struct drm_i915_private *dev_priv = dev->dev_private; |
3790 | struct ilk_pipe_wm_parameters params = {}; |
3701 | struct ilk_wm_maximums max; |
3791 | struct ilk_wm_values results = {}; |
3702 | struct ilk_wm_values results = {}; |
3792 | enum intel_ddb_partitioning partitioning; |
3703 | enum intel_ddb_partitioning partitioning; |
Line 3793... | Line 3704... | ||
3793 | struct intel_pipe_wm pipe_wm = {}; |
3704 | struct intel_pipe_wm pipe_wm = {}; |
Line 3794... | Line 3705... | ||
3794 | struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; |
3705 | struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; |
Line 3795... | Line 3706... | ||
3795 | struct intel_wm_config config = {}; |
3706 | struct intel_wm_config config = {}; |
3796 | 3707 | ||
Line 3797... | Line 3708... | ||
3797 | ilk_compute_wm_parameters(crtc, ¶ms); |
3708 | WARN_ON(cstate->base.active != intel_crtc->active); |
Line 3834... | Line 3745... | ||
3834 | int pixel_size, bool enabled, bool scaled) |
3745 | int pixel_size, bool enabled, bool scaled) |
3835 | { |
3746 | { |
3836 | struct drm_device *dev = plane->dev; |
3747 | struct drm_device *dev = plane->dev; |
3837 | struct intel_plane *intel_plane = to_intel_plane(plane); |
3748 | struct intel_plane *intel_plane = to_intel_plane(plane); |
Line 3838... | Line -... | ||
3838 | - | ||
3839 | intel_plane->wm.enabled = enabled; |
- | |
3840 | intel_plane->wm.scaled = scaled; |
- | |
3841 | intel_plane->wm.horiz_pixels = sprite_width; |
- | |
3842 | intel_plane->wm.vert_pixels = sprite_width; |
- | |
3843 | intel_plane->wm.bytes_per_pixel = pixel_size; |
- | |
3844 | 3749 | ||
3845 | /* |
3750 | /* |
3846 | * IVB workaround: must disable low power watermarks for at least |
3751 | * IVB workaround: must disable low power watermarks for at least |
3847 | * one frame before enabling scaling. LP watermarks can be re-enabled |
3752 | * one frame before enabling scaling. LP watermarks can be re-enabled |
3848 | * when scaling is disabled. |
3753 | * when scaling is disabled. |
Line 3871... | Line 3776... | ||
3871 | val & PLANE_WM_BLOCKS_MASK; |
3776 | val & PLANE_WM_BLOCKS_MASK; |
3872 | active->wm[level].plane_res_l[i] = |
3777 | active->wm[level].plane_res_l[i] = |
3873 | (val >> PLANE_WM_LINES_SHIFT) & |
3778 | (val >> PLANE_WM_LINES_SHIFT) & |
3874 | PLANE_WM_LINES_MASK; |
3779 | PLANE_WM_LINES_MASK; |
3875 | } else { |
3780 | } else { |
3876 | active->wm[level].cursor_en = is_enabled; |
3781 | active->wm[level].plane_en[PLANE_CURSOR] = is_enabled; |
3877 | active->wm[level].cursor_res_b = |
3782 | active->wm[level].plane_res_b[PLANE_CURSOR] = |
3878 | val & PLANE_WM_BLOCKS_MASK; |
3783 | val & PLANE_WM_BLOCKS_MASK; |
3879 | active->wm[level].cursor_res_l = |
3784 | active->wm[level].plane_res_l[PLANE_CURSOR] = |
3880 | (val >> PLANE_WM_LINES_SHIFT) & |
3785 | (val >> PLANE_WM_LINES_SHIFT) & |
3881 | PLANE_WM_LINES_MASK; |
3786 | PLANE_WM_LINES_MASK; |
3882 | } |
3787 | } |
3883 | } else { |
3788 | } else { |
3884 | if (!is_cursor) { |
3789 | if (!is_cursor) { |
Line 3887... | Line 3792... | ||
3887 | val & PLANE_WM_BLOCKS_MASK; |
3792 | val & PLANE_WM_BLOCKS_MASK; |
3888 | active->trans_wm.plane_res_l[i] = |
3793 | active->trans_wm.plane_res_l[i] = |
3889 | (val >> PLANE_WM_LINES_SHIFT) & |
3794 | (val >> PLANE_WM_LINES_SHIFT) & |
3890 | PLANE_WM_LINES_MASK; |
3795 | PLANE_WM_LINES_MASK; |
3891 | } else { |
3796 | } else { |
3892 | active->trans_wm.cursor_en = is_enabled; |
3797 | active->trans_wm.plane_en[PLANE_CURSOR] = is_enabled; |
3893 | active->trans_wm.cursor_res_b = |
3798 | active->trans_wm.plane_res_b[PLANE_CURSOR] = |
3894 | val & PLANE_WM_BLOCKS_MASK; |
3799 | val & PLANE_WM_BLOCKS_MASK; |
3895 | active->trans_wm.cursor_res_l = |
3800 | active->trans_wm.plane_res_l[PLANE_CURSOR] = |
3896 | (val >> PLANE_WM_LINES_SHIFT) & |
3801 | (val >> PLANE_WM_LINES_SHIFT) & |
3897 | PLANE_WM_LINES_MASK; |
3802 | PLANE_WM_LINES_MASK; |
3898 | } |
3803 | } |
3899 | } |
3804 | } |
3900 | } |
3805 | } |
Line 3916... | Line 3821... | ||
3916 | 3821 | ||
3917 | for (level = 0; level <= max_level; level++) { |
3822 | for (level = 0; level <= max_level; level++) { |
3918 | for (i = 0; i < intel_num_planes(intel_crtc); i++) |
3823 | for (i = 0; i < intel_num_planes(intel_crtc); i++) |
3919 | hw->plane[pipe][i][level] = |
3824 | hw->plane[pipe][i][level] = |
3920 | I915_READ(PLANE_WM(pipe, i, level)); |
3825 | I915_READ(PLANE_WM(pipe, i, level)); |
3921 | hw->cursor[pipe][level] = I915_READ(CUR_WM(pipe, level)); |
3826 | hw->plane[pipe][PLANE_CURSOR][level] = I915_READ(CUR_WM(pipe, level)); |
Line 3922... | Line 3827... | ||
3922 | } |
3827 | } |
3923 | 3828 | ||
3924 | for (i = 0; i < intel_num_planes(intel_crtc); i++) |
3829 | for (i = 0; i < intel_num_planes(intel_crtc); i++) |
Line 3925... | Line 3830... | ||
3925 | hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i)); |
3830 | hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i)); |
3926 | hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe)); |
3831 | hw->plane_trans[pipe][PLANE_CURSOR] = I915_READ(CUR_WM_TRANS(pipe)); |
Line 3927... | Line 3832... | ||
3927 | 3832 | ||
Line 3928... | Line 3833... | ||
3928 | if (!intel_crtc_active(crtc)) |
3833 | if (!intel_crtc->active) |
Line 3936... | Line 3841... | ||
3936 | for (i = 0; i < intel_num_planes(intel_crtc); i++) { |
3841 | for (i = 0; i < intel_num_planes(intel_crtc); i++) { |
3937 | temp = hw->plane[pipe][i][level]; |
3842 | temp = hw->plane[pipe][i][level]; |
3938 | skl_pipe_wm_active_state(temp, active, false, |
3843 | skl_pipe_wm_active_state(temp, active, false, |
3939 | false, i, level); |
3844 | false, i, level); |
3940 | } |
3845 | } |
3941 | temp = hw->cursor[pipe][level]; |
3846 | temp = hw->plane[pipe][PLANE_CURSOR][level]; |
3942 | skl_pipe_wm_active_state(temp, active, false, true, i, level); |
3847 | skl_pipe_wm_active_state(temp, active, false, true, i, level); |
3943 | } |
3848 | } |
Line 3944... | Line 3849... | ||
3944 | 3849 | ||
3945 | for (i = 0; i < intel_num_planes(intel_crtc); i++) { |
3850 | for (i = 0; i < intel_num_planes(intel_crtc); i++) { |
3946 | temp = hw->plane_trans[pipe][i]; |
3851 | temp = hw->plane_trans[pipe][i]; |
3947 | skl_pipe_wm_active_state(temp, active, true, false, i, 0); |
3852 | skl_pipe_wm_active_state(temp, active, true, false, i, 0); |
Line 3948... | Line 3853... | ||
3948 | } |
3853 | } |
3949 | 3854 | ||
3950 | temp = hw->cursor_trans[pipe]; |
3855 | temp = hw->plane_trans[pipe][PLANE_CURSOR]; |
Line 3951... | Line 3856... | ||
3951 | skl_pipe_wm_active_state(temp, active, true, true, i, 0); |
3856 | skl_pipe_wm_active_state(temp, active, true, true, i, 0); |
3952 | } |
3857 | } |
Line 3978... | Line 3883... | ||
3978 | 3883 | ||
3979 | hw->wm_pipe[pipe] = I915_READ(wm0_pipe_reg[pipe]); |
3884 | hw->wm_pipe[pipe] = I915_READ(wm0_pipe_reg[pipe]); |
3980 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
3885 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
Line 3981... | Line 3886... | ||
3981 | hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe)); |
3886 | hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe)); |
Line 3982... | Line 3887... | ||
3982 | 3887 | ||
3983 | active->pipe_enabled = intel_crtc_active(crtc); |
3888 | active->pipe_enabled = intel_crtc->active; |
Line 3984... | Line 3889... | ||
3984 | 3889 | ||
Line 4007... | Line 3912... | ||
4007 | for (level = 0; level <= max_level; level++) |
3912 | for (level = 0; level <= max_level; level++) |
4008 | active->wm[level].enable = true; |
3913 | active->wm[level].enable = true; |
4009 | } |
3914 | } |
4010 | } |
3915 | } |
Line -... | Line 3916... | ||
- | 3916 | ||
- | 3917 | #define _FW_WM(value, plane) \ |
|
- | 3918 | (((value) & DSPFW_ ## plane ## _MASK) >> DSPFW_ ## plane ## _SHIFT) |
|
- | 3919 | #define _FW_WM_VLV(value, plane) \ |
|
- | 3920 | (((value) & DSPFW_ ## plane ## _MASK_VLV) >> DSPFW_ ## plane ## _SHIFT) |
|
- | 3921 | ||
- | 3922 | static void vlv_read_wm_values(struct drm_i915_private *dev_priv, |
|
- | 3923 | struct vlv_wm_values *wm) |
|
- | 3924 | { |
|
- | 3925 | enum pipe pipe; |
|
- | 3926 | uint32_t tmp; |
|
- | 3927 | ||
- | 3928 | for_each_pipe(dev_priv, pipe) { |
|
- | 3929 | tmp = I915_READ(VLV_DDL(pipe)); |
|
- | 3930 | ||
- | 3931 | wm->ddl[pipe].primary = |
|
- | 3932 | (tmp >> DDL_PLANE_SHIFT) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK); |
|
- | 3933 | wm->ddl[pipe].cursor = |
|
- | 3934 | (tmp >> DDL_CURSOR_SHIFT) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK); |
|
- | 3935 | wm->ddl[pipe].sprite[0] = |
|
- | 3936 | (tmp >> DDL_SPRITE_SHIFT(0)) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK); |
|
- | 3937 | wm->ddl[pipe].sprite[1] = |
|
- | 3938 | (tmp >> DDL_SPRITE_SHIFT(1)) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK); |
|
- | 3939 | } |
|
- | 3940 | ||
- | 3941 | tmp = I915_READ(DSPFW1); |
|
- | 3942 | wm->sr.plane = _FW_WM(tmp, SR); |
|
- | 3943 | wm->pipe[PIPE_B].cursor = _FW_WM(tmp, CURSORB); |
|
- | 3944 | wm->pipe[PIPE_B].primary = _FW_WM_VLV(tmp, PLANEB); |
|
- | 3945 | wm->pipe[PIPE_A].primary = _FW_WM_VLV(tmp, PLANEA); |
|
- | 3946 | ||
- | 3947 | tmp = I915_READ(DSPFW2); |
|
- | 3948 | wm->pipe[PIPE_A].sprite[1] = _FW_WM_VLV(tmp, SPRITEB); |
|
- | 3949 | wm->pipe[PIPE_A].cursor = _FW_WM(tmp, CURSORA); |
|
- | 3950 | wm->pipe[PIPE_A].sprite[0] = _FW_WM_VLV(tmp, SPRITEA); |
|
- | 3951 | ||
- | 3952 | tmp = I915_READ(DSPFW3); |
|
- | 3953 | wm->sr.cursor = _FW_WM(tmp, CURSOR_SR); |
|
- | 3954 | ||
- | 3955 | if (IS_CHERRYVIEW(dev_priv)) { |
|
- | 3956 | tmp = I915_READ(DSPFW7_CHV); |
|
- | 3957 | wm->pipe[PIPE_B].sprite[1] = _FW_WM_VLV(tmp, SPRITED); |
|
- | 3958 | wm->pipe[PIPE_B].sprite[0] = _FW_WM_VLV(tmp, SPRITEC); |
|
- | 3959 | ||
- | 3960 | tmp = I915_READ(DSPFW8_CHV); |
|
- | 3961 | wm->pipe[PIPE_C].sprite[1] = _FW_WM_VLV(tmp, SPRITEF); |
|
- | 3962 | wm->pipe[PIPE_C].sprite[0] = _FW_WM_VLV(tmp, SPRITEE); |
|
- | 3963 | ||
- | 3964 | tmp = I915_READ(DSPFW9_CHV); |
|
- | 3965 | wm->pipe[PIPE_C].primary = _FW_WM_VLV(tmp, PLANEC); |
|
- | 3966 | wm->pipe[PIPE_C].cursor = _FW_WM(tmp, CURSORC); |
|
- | 3967 | ||
- | 3968 | tmp = I915_READ(DSPHOWM); |
|
- | 3969 | wm->sr.plane |= _FW_WM(tmp, SR_HI) << 9; |
|
- | 3970 | wm->pipe[PIPE_C].sprite[1] |= _FW_WM(tmp, SPRITEF_HI) << 8; |
|
- | 3971 | wm->pipe[PIPE_C].sprite[0] |= _FW_WM(tmp, SPRITEE_HI) << 8; |
|
- | 3972 | wm->pipe[PIPE_C].primary |= _FW_WM(tmp, PLANEC_HI) << 8; |
|
- | 3973 | wm->pipe[PIPE_B].sprite[1] |= _FW_WM(tmp, SPRITED_HI) << 8; |
|
- | 3974 | wm->pipe[PIPE_B].sprite[0] |= _FW_WM(tmp, SPRITEC_HI) << 8; |
|
- | 3975 | wm->pipe[PIPE_B].primary |= _FW_WM(tmp, PLANEB_HI) << 8; |
|
- | 3976 | wm->pipe[PIPE_A].sprite[1] |= _FW_WM(tmp, SPRITEB_HI) << 8; |
|
- | 3977 | wm->pipe[PIPE_A].sprite[0] |= _FW_WM(tmp, SPRITEA_HI) << 8; |
|
- | 3978 | wm->pipe[PIPE_A].primary |= _FW_WM(tmp, PLANEA_HI) << 8; |
|
- | 3979 | } else { |
|
- | 3980 | tmp = I915_READ(DSPFW7); |
|
- | 3981 | wm->pipe[PIPE_B].sprite[1] = _FW_WM_VLV(tmp, SPRITED); |
|
- | 3982 | wm->pipe[PIPE_B].sprite[0] = _FW_WM_VLV(tmp, SPRITEC); |
|
- | 3983 | ||
- | 3984 | tmp = I915_READ(DSPHOWM); |
|
- | 3985 | wm->sr.plane |= _FW_WM(tmp, SR_HI) << 9; |
|
- | 3986 | wm->pipe[PIPE_B].sprite[1] |= _FW_WM(tmp, SPRITED_HI) << 8; |
|
- | 3987 | wm->pipe[PIPE_B].sprite[0] |= _FW_WM(tmp, SPRITEC_HI) << 8; |
|
- | 3988 | wm->pipe[PIPE_B].primary |= _FW_WM(tmp, PLANEB_HI) << 8; |
|
- | 3989 | wm->pipe[PIPE_A].sprite[1] |= _FW_WM(tmp, SPRITEB_HI) << 8; |
|
- | 3990 | wm->pipe[PIPE_A].sprite[0] |= _FW_WM(tmp, SPRITEA_HI) << 8; |
|
- | 3991 | wm->pipe[PIPE_A].primary |= _FW_WM(tmp, PLANEA_HI) << 8; |
|
- | 3992 | } |
|
- | 3993 | } |
|
- | 3994 | ||
- | 3995 | #undef _FW_WM |
|
- | 3996 | #undef _FW_WM_VLV |
|
- | 3997 | ||
- | 3998 | void vlv_wm_get_hw_state(struct drm_device *dev) |
|
- | 3999 | { |
|
- | 4000 | struct drm_i915_private *dev_priv = to_i915(dev); |
|
- | 4001 | struct vlv_wm_values *wm = &dev_priv->wm.vlv; |
|
- | 4002 | struct intel_plane *plane; |
|
- | 4003 | enum pipe pipe; |
|
- | 4004 | u32 val; |
|
- | 4005 | ||
- | 4006 | vlv_read_wm_values(dev_priv, wm); |
|
- | 4007 | ||
- | 4008 | for_each_intel_plane(dev, plane) { |
|
- | 4009 | switch (plane->base.type) { |
|
- | 4010 | int sprite; |
|
- | 4011 | case DRM_PLANE_TYPE_CURSOR: |
|
- | 4012 | plane->wm.fifo_size = 63; |
|
- | 4013 | break; |
|
- | 4014 | case DRM_PLANE_TYPE_PRIMARY: |
|
- | 4015 | plane->wm.fifo_size = vlv_get_fifo_size(dev, plane->pipe, 0); |
|
- | 4016 | break; |
|
- | 4017 | case DRM_PLANE_TYPE_OVERLAY: |
|
- | 4018 | sprite = plane->plane; |
|
- | 4019 | plane->wm.fifo_size = vlv_get_fifo_size(dev, plane->pipe, sprite + 1); |
|
- | 4020 | break; |
|
- | 4021 | } |
|
- | 4022 | } |
|
- | 4023 | ||
- | 4024 | wm->cxsr = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; |
|
- | 4025 | wm->level = VLV_WM_LEVEL_PM2; |
|
- | 4026 | ||
- | 4027 | if (IS_CHERRYVIEW(dev_priv)) { |
|
- | 4028 | mutex_lock(&dev_priv->rps.hw_lock); |
|
- | 4029 | ||
- | 4030 | val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); |
|
- | 4031 | if (val & DSP_MAXFIFO_PM5_ENABLE) |
|
- | 4032 | wm->level = VLV_WM_LEVEL_PM5; |
|
- | 4033 | ||
- | 4034 | /* |
|
- | 4035 | * If DDR DVFS is disabled in the BIOS, Punit |
|
- | 4036 | * will never ack the request. So if that happens |
|
- | 4037 | * assume we don't have to enable/disable DDR DVFS |
|
- | 4038 | * dynamically. To test that just set the REQ_ACK |
|
- | 4039 | * bit to poke the Punit, but don't change the |
|
- | 4040 | * HIGH/LOW bits so that we don't actually change |
|
- | 4041 | * the current state. |
|
- | 4042 | */ |
|
- | 4043 | val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2); |
|
- | 4044 | val |= FORCE_DDR_FREQ_REQ_ACK; |
|
- | 4045 | vlv_punit_write(dev_priv, PUNIT_REG_DDR_SETUP2, val); |
|
- | 4046 | ||
- | 4047 | if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) & |
|
- | 4048 | FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) { |
|
- | 4049 | DRM_DEBUG_KMS("Punit not acking DDR DVFS request, " |
|
- | 4050 | "assuming DDR DVFS is disabled\n"); |
|
- | 4051 | dev_priv->wm.max_level = VLV_WM_LEVEL_PM5; |
|
- | 4052 | } else { |
|
- | 4053 | val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2); |
|
- | 4054 | if ((val & FORCE_DDR_HIGH_FREQ) == 0) |
|
- | 4055 | wm->level = VLV_WM_LEVEL_DDR_DVFS; |
|
- | 4056 | } |
|
- | 4057 | ||
- | 4058 | mutex_unlock(&dev_priv->rps.hw_lock); |
|
- | 4059 | } |
|
- | 4060 | ||
- | 4061 | for_each_pipe(dev_priv, pipe) |
|
- | 4062 | DRM_DEBUG_KMS("Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite0=%d, sprite1=%d\n", |
|
- | 4063 | pipe_name(pipe), wm->pipe[pipe].primary, wm->pipe[pipe].cursor, |
|
- | 4064 | wm->pipe[pipe].sprite[0], wm->pipe[pipe].sprite[1]); |
|
- | 4065 | ||
- | 4066 | DRM_DEBUG_KMS("Initial watermarks: SR plane=%d, SR cursor=%d level=%d cxsr=%d\n", |
|
- | 4067 | wm->sr.plane, wm->sr.cursor, wm->level, wm->cxsr); |
|
- | 4068 | } |
|
4011 | 4069 | ||
4012 | void ilk_wm_get_hw_state(struct drm_device *dev) |
4070 | void ilk_wm_get_hw_state(struct drm_device *dev) |
4013 | { |
4071 | { |
4014 | struct drm_i915_private *dev_priv = dev->dev_private; |
4072 | struct drm_i915_private *dev_priv = dev->dev_private; |
4015 | struct ilk_wm_values *hw = &dev_priv->wm.hw; |
4073 | struct ilk_wm_values *hw = &dev_priv->wm.hw; |
Line 4092... | Line 4150... | ||
4092 | dev_priv->display.update_sprite_wm(plane, crtc, |
4150 | dev_priv->display.update_sprite_wm(plane, crtc, |
4093 | sprite_width, sprite_height, |
4151 | sprite_width, sprite_height, |
4094 | pixel_size, enabled, scaled); |
4152 | pixel_size, enabled, scaled); |
4095 | } |
4153 | } |
Line 4096... | Line -... | ||
4096 | - | ||
4097 | static struct drm_i915_gem_object * |
- | |
4098 | intel_alloc_context_page(struct drm_device *dev) |
- | |
4099 | { |
- | |
4100 | struct drm_i915_gem_object *ctx; |
- | |
4101 | int ret; |
- | |
4102 | - | ||
4103 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); |
- | |
4104 | - | ||
4105 | ctx = i915_gem_alloc_object(dev, 4096); |
- | |
4106 | if (!ctx) { |
- | |
4107 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); |
- | |
4108 | return NULL; |
- | |
4109 | } |
- | |
4110 | - | ||
4111 | ret = i915_gem_obj_ggtt_pin(ctx, 4096, 0); |
- | |
4112 | if (ret) { |
- | |
4113 | DRM_ERROR("failed to pin power context: %d\n", ret); |
- | |
4114 | goto err_unref; |
- | |
4115 | } |
- | |
4116 | - | ||
4117 | ret = i915_gem_object_set_to_gtt_domain(ctx, 1); |
- | |
4118 | if (ret) { |
- | |
4119 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); |
- | |
4120 | goto err_unpin; |
- | |
4121 | } |
- | |
4122 | - | ||
4123 | return ctx; |
- | |
4124 | - | ||
4125 | err_unpin: |
- | |
4126 | i915_gem_object_ggtt_unpin(ctx); |
- | |
4127 | err_unref: |
- | |
4128 | drm_gem_object_unreference(&ctx->base); |
- | |
4129 | return NULL; |
- | |
4130 | } |
- | |
4131 | 4154 | ||
4132 | /** |
4155 | /** |
4133 | * Lock protecting IPS related data structures |
4156 | * Lock protecting IPS related data structures |
4134 | */ |
4157 | */ |
Line 4188... | Line 4211... | ||
4188 | fmax = (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT; |
4211 | fmax = (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT; |
4189 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); |
4212 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); |
4190 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> |
4213 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> |
4191 | MEMMODE_FSTART_SHIFT; |
4214 | MEMMODE_FSTART_SHIFT; |
Line 4192... | Line 4215... | ||
4192 | 4215 | ||
4193 | vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> |
4216 | vstart = (I915_READ(PXVFREQ(fstart)) & PXVFREQ_PX_MASK) >> |
Line 4194... | Line 4217... | ||
4194 | PXVFREQ_PX_SHIFT; |
4217 | PXVFREQ_PX_SHIFT; |
4195 | 4218 | ||
Line 4219... | Line 4242... | ||
4219 | DRM_ERROR("stuck trying to change perf mode\n"); |
4242 | DRM_ERROR("stuck trying to change perf mode\n"); |
4220 | mdelay(1); |
4243 | mdelay(1); |
Line 4221... | Line 4244... | ||
4221 | 4244 | ||
Line 4222... | Line 4245... | ||
4222 | ironlake_set_drps(dev, fstart); |
4245 | ironlake_set_drps(dev, fstart); |
4223 | 4246 | ||
4224 | dev_priv->ips.last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) + |
4247 | dev_priv->ips.last_count1 = I915_READ(DMIEC) + |
4225 | I915_READ(0x112e0); |
4248 | I915_READ(DDREC) + I915_READ(CSIEC); |
4226 | dev_priv->ips.last_time1 = jiffies_to_msecs(jiffies); |
4249 | dev_priv->ips.last_time1 = jiffies_to_msecs(jiffies); |
Line 4227... | Line 4250... | ||
4227 | dev_priv->ips.last_count2 = I915_READ(0x112f4); |
4250 | dev_priv->ips.last_count2 = I915_READ(GFXEC); |
4228 | dev_priv->ips.last_time2 = ktime_get_raw_ns(); |
4251 | dev_priv->ips.last_time2 = ktime_get_raw_ns(); |
Line 4259... | Line 4282... | ||
4259 | /* There's a funny hw issue where the hw returns all 0 when reading from |
4282 | /* There's a funny hw issue where the hw returns all 0 when reading from |
4260 | * GEN6_RP_INTERRUPT_LIMITS. Hence we always need to compute the desired value |
4283 | * GEN6_RP_INTERRUPT_LIMITS. Hence we always need to compute the desired value |
4261 | * ourselves, instead of doing a rmw cycle (which might result in us clearing |
4284 | * ourselves, instead of doing a rmw cycle (which might result in us clearing |
4262 | * all limits and the gpu stuck at whatever frequency it is at atm). |
4285 | * all limits and the gpu stuck at whatever frequency it is at atm). |
4263 | */ |
4286 | */ |
4264 | static u32 gen6_rps_limits(struct drm_i915_private *dev_priv, u8 val) |
4287 | static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val) |
4265 | { |
4288 | { |
4266 | u32 limits; |
4289 | u32 limits; |
Line 4267... | Line 4290... | ||
4267 | 4290 | ||
4268 | /* Only set the down limit when we've reached the lowest level to avoid |
4291 | /* Only set the down limit when we've reached the lowest level to avoid |
4269 | * getting more interrupts, otherwise leave this clear. This prevents a |
4292 | * getting more interrupts, otherwise leave this clear. This prevents a |
4270 | * race in the hw when coming out of rc6: There's a tiny window where |
4293 | * race in the hw when coming out of rc6: There's a tiny window where |
4271 | * the hw runs at the minimal clock before selecting the desired |
4294 | * the hw runs at the minimal clock before selecting the desired |
4272 | * frequency, if the down threshold expires in that window we will not |
4295 | * frequency, if the down threshold expires in that window we will not |
- | 4296 | * receive a down interrupt. */ |
|
- | 4297 | if (IS_GEN9(dev_priv->dev)) { |
|
- | 4298 | limits = (dev_priv->rps.max_freq_softlimit) << 23; |
|
- | 4299 | if (val <= dev_priv->rps.min_freq_softlimit) |
|
- | 4300 | limits |= (dev_priv->rps.min_freq_softlimit) << 14; |
|
4273 | * receive a down interrupt. */ |
4301 | } else { |
4274 | limits = dev_priv->rps.max_freq_softlimit << 24; |
4302 | limits = dev_priv->rps.max_freq_softlimit << 24; |
4275 | if (val <= dev_priv->rps.min_freq_softlimit) |
4303 | if (val <= dev_priv->rps.min_freq_softlimit) |
- | 4304 | limits |= dev_priv->rps.min_freq_softlimit << 16; |
|
Line 4276... | Line 4305... | ||
4276 | limits |= dev_priv->rps.min_freq_softlimit << 16; |
4305 | } |
4277 | 4306 | ||
Line 4278... | Line 4307... | ||
4278 | return limits; |
4307 | return limits; |
4279 | } |
4308 | } |
4280 | 4309 | ||
- | 4310 | static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) |
|
- | 4311 | { |
|
Line 4281... | Line 4312... | ||
4281 | static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) |
4312 | int new_power; |
4282 | { |
4313 | u32 threshold_up = 0, threshold_down = 0; /* in % */ |
4283 | int new_power; |
4314 | u32 ei_up = 0, ei_down = 0; |
4284 | 4315 | ||
Line 4300... | Line 4331... | ||
4300 | if (val < (dev_priv->rps.rp1_freq + dev_priv->rps.rp0_freq) >> 1 && val < dev_priv->rps.cur_freq) |
4331 | if (val < (dev_priv->rps.rp1_freq + dev_priv->rps.rp0_freq) >> 1 && val < dev_priv->rps.cur_freq) |
4301 | new_power = BETWEEN; |
4332 | new_power = BETWEEN; |
4302 | break; |
4333 | break; |
4303 | } |
4334 | } |
4304 | /* Max/min bins are special */ |
4335 | /* Max/min bins are special */ |
4305 | if (val == dev_priv->rps.min_freq_softlimit) |
4336 | if (val <= dev_priv->rps.min_freq_softlimit) |
4306 | new_power = LOW_POWER; |
4337 | new_power = LOW_POWER; |
4307 | if (val == dev_priv->rps.max_freq_softlimit) |
4338 | if (val >= dev_priv->rps.max_freq_softlimit) |
4308 | new_power = HIGH_POWER; |
4339 | new_power = HIGH_POWER; |
4309 | if (new_power == dev_priv->rps.power) |
4340 | if (new_power == dev_priv->rps.power) |
4310 | return; |
4341 | return; |
Line 4311... | Line 4342... | ||
4311 | 4342 | ||
4312 | /* Note the units here are not exactly 1us, but 1280ns. */ |
4343 | /* Note the units here are not exactly 1us, but 1280ns. */ |
4313 | switch (new_power) { |
4344 | switch (new_power) { |
4314 | case LOW_POWER: |
4345 | case LOW_POWER: |
4315 | /* Upclock if more than 95% busy over 16ms */ |
4346 | /* Upclock if more than 95% busy over 16ms */ |
4316 | I915_WRITE(GEN6_RP_UP_EI, 12500); |
4347 | ei_up = 16000; |
Line 4317... | Line 4348... | ||
4317 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 11800); |
4348 | threshold_up = 95; |
4318 | - | ||
4319 | /* Downclock if less than 85% busy over 32ms */ |
- | |
4320 | I915_WRITE(GEN6_RP_DOWN_EI, 25000); |
- | |
4321 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 21250); |
- | |
4322 | 4349 | ||
4323 | I915_WRITE(GEN6_RP_CONTROL, |
- | |
4324 | GEN6_RP_MEDIA_TURBO | |
- | |
4325 | GEN6_RP_MEDIA_HW_NORMAL_MODE | |
4350 | /* Downclock if less than 85% busy over 32ms */ |
4326 | GEN6_RP_MEDIA_IS_GFX | |
- | |
4327 | GEN6_RP_ENABLE | |
- | |
4328 | GEN6_RP_UP_BUSY_AVG | |
4351 | ei_down = 32000; |
Line 4329... | Line 4352... | ||
4329 | GEN6_RP_DOWN_IDLE_AVG); |
4352 | threshold_down = 85; |
4330 | break; |
4353 | break; |
4331 | 4354 | ||
4332 | case BETWEEN: |
4355 | case BETWEEN: |
Line 4333... | Line 4356... | ||
4333 | /* Upclock if more than 90% busy over 13ms */ |
4356 | /* Upclock if more than 90% busy over 13ms */ |
4334 | I915_WRITE(GEN6_RP_UP_EI, 10250); |
- | |
4335 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 9225); |
- | |
4336 | - | ||
4337 | /* Downclock if less than 75% busy over 32ms */ |
- | |
4338 | I915_WRITE(GEN6_RP_DOWN_EI, 25000); |
4357 | ei_up = 13000; |
4339 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 18750); |
- | |
4340 | - | ||
4341 | I915_WRITE(GEN6_RP_CONTROL, |
4358 | threshold_up = 90; |
4342 | GEN6_RP_MEDIA_TURBO | |
- | |
4343 | GEN6_RP_MEDIA_HW_NORMAL_MODE | |
- | |
4344 | GEN6_RP_MEDIA_IS_GFX | |
4359 | |
Line 4345... | Line 4360... | ||
4345 | GEN6_RP_ENABLE | |
4360 | /* Downclock if less than 75% busy over 32ms */ |
4346 | GEN6_RP_UP_BUSY_AVG | |
4361 | ei_down = 32000; |
4347 | GEN6_RP_DOWN_IDLE_AVG); |
4362 | threshold_down = 75; |
4348 | break; |
4363 | break; |
Line 4349... | Line 4364... | ||
4349 | 4364 | ||
- | 4365 | case HIGH_POWER: |
|
- | 4366 | /* Upclock if more than 85% busy over 10ms */ |
|
- | 4367 | ei_up = 10000; |
|
- | 4368 | threshold_up = 85; |
|
- | 4369 | ||
- | 4370 | /* Downclock if less than 60% busy over 32ms */ |
|
- | 4371 | ei_down = 32000; |
|
- | 4372 | threshold_down = 60; |
|
- | 4373 | break; |
|
- | 4374 | } |
|
4350 | case HIGH_POWER: |
4375 | |
- | 4376 | I915_WRITE(GEN6_RP_UP_EI, |
|
4351 | /* Upclock if more than 85% busy over 10ms */ |
4377 | GT_INTERVAL_FROM_US(dev_priv, ei_up)); |
- | 4378 | I915_WRITE(GEN6_RP_UP_THRESHOLD, |
|
Line 4352... | Line 4379... | ||
4352 | I915_WRITE(GEN6_RP_UP_EI, 8000); |
4379 | GT_INTERVAL_FROM_US(dev_priv, (ei_up * threshold_up / 100))); |
4353 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 6800); |
4380 | |
4354 | 4381 | I915_WRITE(GEN6_RP_DOWN_EI, |
|
4355 | /* Downclock if less than 60% busy over 32ms */ |
4382 | GT_INTERVAL_FROM_US(dev_priv, ei_down)); |
4356 | I915_WRITE(GEN6_RP_DOWN_EI, 25000); |
4383 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, |
4357 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 15000); |
4384 | GT_INTERVAL_FROM_US(dev_priv, (ei_down * threshold_down / 100))); |
4358 | 4385 | ||
4359 | I915_WRITE(GEN6_RP_CONTROL, |
- | |
4360 | GEN6_RP_MEDIA_TURBO | |
- | |
Line 4361... | Line 4386... | ||
4361 | GEN6_RP_MEDIA_HW_NORMAL_MODE | |
4386 | I915_WRITE(GEN6_RP_CONTROL, |
- | 4387 | GEN6_RP_MEDIA_TURBO | |
|
- | 4388 | GEN6_RP_MEDIA_HW_NORMAL_MODE | |
|
4362 | GEN6_RP_MEDIA_IS_GFX | |
4389 | GEN6_RP_MEDIA_IS_GFX | |
4363 | GEN6_RP_ENABLE | |
4390 | GEN6_RP_ENABLE | |
Line 4364... | Line 4391... | ||
4364 | GEN6_RP_UP_BUSY_AVG | |
4391 | GEN6_RP_UP_BUSY_AVG | |
4365 | GEN6_RP_DOWN_IDLE_AVG); |
4392 | GEN6_RP_DOWN_IDLE_AVG); |
4366 | break; |
4393 | |
Line 4367... | Line 4394... | ||
4367 | } |
4394 | dev_priv->rps.power = new_power; |
4368 | 4395 | dev_priv->rps.up_threshold = threshold_up; |
|
4369 | dev_priv->rps.power = new_power; |
4396 | dev_priv->rps.down_threshold = threshold_down; |
4370 | dev_priv->rps.last_adj = 0; |
4397 | dev_priv->rps.last_adj = 0; |
Line 4371... | Line -... | ||
4371 | } |
- | |
4372 | 4398 | } |
|
Line 4373... | Line -... | ||
4373 | static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) |
- | |
4374 | { |
4399 | |
4375 | u32 mask = 0; |
- | |
4376 | - | ||
4377 | if (val > dev_priv->rps.min_freq_softlimit) |
- | |
4378 | mask |= GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; |
- | |
4379 | if (val < dev_priv->rps.max_freq_softlimit) |
- | |
4380 | mask |= GEN6_PM_RP_UP_THRESHOLD; |
- | |
4381 | - | ||
4382 | mask |= dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED); |
- | |
4383 | mask &= dev_priv->pm_rps_events; |
4400 | static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) |
Line 4384... | Line 4401... | ||
4384 | 4401 | { |
|
4385 | /* IVB and SNB hard hangs on looping batchbuffer |
4402 | u32 mask = 0; |
4386 | * if GEN6_PM_UP_EI_EXPIRED is masked. |
4403 | |
4387 | */ |
4404 | if (val > dev_priv->rps.min_freq_softlimit) |
4388 | if (INTEL_INFO(dev_priv->dev)->gen <= 7 && !IS_HASWELL(dev_priv->dev)) |
4405 | mask |= GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; |
4389 | mask |= GEN6_PM_RP_UP_EI_EXPIRED; |
4406 | if (val < dev_priv->rps.max_freq_softlimit) |
Line -... | Line 4407... | ||
- | 4407 | mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD; |
|
- | 4408 | ||
- | 4409 | mask &= dev_priv->pm_rps_events; |
|
- | 4410 | ||
4390 | 4411 | return gen6_sanitize_rps_pm_mask(dev_priv, ~mask); |
|
4391 | if (IS_GEN8(dev_priv->dev)) |
4412 | } |
4392 | mask |= GEN8_PMINTR_REDIRECT_TO_NON_DISP; |
4413 | |
Line 4393... | Line 4414... | ||
4393 | 4414 | /* gen6_set_rps is called to update the frequency request, but should also be |
|
4394 | return ~mask; |
4415 | * called when the range (min_delay and max_delay) is modified so that we can |
4395 | } |
4416 | * update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */ |
4396 | 4417 | static void gen6_set_rps(struct drm_device *dev, u8 val) |
|
4397 | /* gen6_set_rps is called to update the frequency request, but should also be |
4418 | { |
Line -... | Line 4419... | ||
- | 4419 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 4420 | ||
- | 4421 | /* WaGsvDisableTurbo: Workaround to disable turbo on BXT A* */ |
|
4398 | * called when the range (min_delay and max_delay) is modified so that we can |
4422 | if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) |
4399 | * update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */ |
4423 | return; |
4400 | void gen6_set_rps(struct drm_device *dev, u8 val) |
4424 | |
4401 | { |
4425 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
4402 | struct drm_i915_private *dev_priv = dev->dev_private; |
4426 | WARN_ON(val > dev_priv->rps.max_freq); |
4403 | 4427 | WARN_ON(val < dev_priv->rps.min_freq); |
|
Line 4422... | Line 4446... | ||
4422 | } |
4446 | } |
Line 4423... | Line 4447... | ||
4423 | 4447 | ||
4424 | /* Make sure we continue to get interrupts |
4448 | /* Make sure we continue to get interrupts |
4425 | * until we hit the minimum or maximum frequencies. |
4449 | * until we hit the minimum or maximum frequencies. |
4426 | */ |
4450 | */ |
4427 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, gen6_rps_limits(dev_priv, val)); |
4451 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, intel_rps_limits(dev_priv, val)); |
Line 4428... | Line 4452... | ||
4428 | I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); |
4452 | I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); |
Line 4429... | Line 4453... | ||
4429 | 4453 | ||
4430 | POSTING_READ(GEN6_RPNSWREQ); |
4454 | POSTING_READ(GEN6_RPNSWREQ); |
4431 | 4455 | ||
Line 4432... | Line -... | ||
4432 | dev_priv->rps.cur_freq = val; |
- | |
4433 | trace_intel_gpu_freq_change(val * 50); |
- | |
4434 | } |
- | |
4435 | - | ||
4436 | /* vlv_set_rps_idle: Set the frequency to Rpn if Gfx clocks are down |
- | |
4437 | * |
- | |
4438 | * * If Gfx is Idle, then |
- | |
4439 | * 1. Mask Turbo interrupts |
- | |
4440 | * 2. Bring up Gfx clock |
- | |
4441 | * 3. Change the freq to Rpn and wait till P-Unit updates freq |
4456 | dev_priv->rps.cur_freq = val; |
4442 | * 4. Clear the Force GFX CLK ON bit so that Gfx can down |
4457 | trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); |
4443 | * 5. Unmask Turbo interrupts |
4458 | } |
4444 | */ |
- | |
4445 | static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) |
- | |
4446 | { |
- | |
4447 | struct drm_device *dev = dev_priv->dev; |
- | |
4448 | - | ||
4449 | /* Latest VLV doesn't need to force the gfx clock */ |
- | |
4450 | if (dev->pdev->revision >= 0xd) { |
- | |
4451 | valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); |
- | |
4452 | return; |
- | |
4453 | } |
- | |
Line -... | Line 4459... | ||
- | 4459 | ||
4454 | 4460 | static void valleyview_set_rps(struct drm_device *dev, u8 val) |
|
4455 | /* |
4461 | { |
Line 4456... | Line 4462... | ||
4456 | * When we are idle. Drop to min voltage state. |
4462 | struct drm_i915_private *dev_priv = dev->dev_private; |
4457 | */ |
4463 | |
- | 4464 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
|
Line 4458... | Line 4465... | ||
4458 | 4465 | WARN_ON(val > dev_priv->rps.max_freq); |
|
Line 4459... | Line 4466... | ||
4459 | if (dev_priv->rps.cur_freq <= dev_priv->rps.min_freq_softlimit) |
4466 | WARN_ON(val < dev_priv->rps.min_freq); |
- | 4467 | ||
- | 4468 | if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1), |
|
- | 4469 | "Odd GPU freq value\n")) |
|
- | 4470 | val &= ~1; |
|
Line 4460... | Line 4471... | ||
4460 | return; |
4471 | |
4461 | 4472 | I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); |
|
- | 4473 | ||
Line 4462... | Line 4474... | ||
4462 | /* Mask turbo interrupt so that they will not come in between */ |
4474 | if (val != dev_priv->rps.cur_freq) { |
- | 4475 | vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); |
|
- | 4476 | if (!IS_CHERRYVIEW(dev_priv)) |
|
4463 | I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); |
4477 | gen6_set_rps_thresholds(dev_priv, val); |
- | 4478 | } |
|
4464 | 4479 | ||
- | 4480 | dev_priv->rps.cur_freq = val; |
|
- | 4481 | trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); |
|
- | 4482 | } |
|
- | 4483 | ||
Line 4465... | Line 4484... | ||
4465 | vlv_force_gfx_clock(dev_priv, true); |
4484 | /* vlv_set_rps_idle: Set the frequency to idle, if Gfx clocks are down |
- | 4485 | * |
|
Line -... | Line 4486... | ||
- | 4486 | * * If Gfx is Idle, then |
|
- | 4487 | * 1. Forcewake Media well. |
|
- | 4488 | * 2. Request idle freq. |
|
4466 | 4489 | * 3. Release Forcewake of Media well. |
|
4467 | dev_priv->rps.cur_freq = dev_priv->rps.min_freq_softlimit; |
4490 | */ |
4468 | 4491 | static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) |
|
Line 4469... | Line 4492... | ||
4469 | vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, |
4492 | { |
4470 | dev_priv->rps.min_freq_softlimit); |
4493 | u32 val = dev_priv->rps.idle_freq; |
4471 | - | ||
4472 | if (wait_for(((vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS)) |
- | |
4473 | & GENFREQSTATUS) == 0, 100)) |
4494 | |
4474 | DRM_ERROR("timed out waiting for Punit\n"); |
4495 | if (dev_priv->rps.cur_freq <= val) |
4475 | - | ||
4476 | vlv_force_gfx_clock(dev_priv, false); |
4496 | return; |
4477 | 4497 | ||
4478 | I915_WRITE(GEN6_PMINTRMSK, |
4498 | /* Wake up the media well, as that takes a lot less |
4479 | gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); |
- | |
4480 | } |
4499 | * power than the Render well. */ |
4481 | - | ||
4482 | void gen6_rps_idle(struct drm_i915_private *dev_priv) |
4500 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_MEDIA); |
4483 | { |
4501 | valleyview_set_rps(dev_priv->dev, val); |
4484 | struct drm_device *dev = dev_priv->dev; |
4502 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_MEDIA); |
Line 4485... | Line 4503... | ||
4485 | 4503 | } |
|
4486 | mutex_lock(&dev_priv->rps.hw_lock); |
4504 | |
4487 | if (dev_priv->rps.enabled) { |
4505 | void gen6_rps_busy(struct drm_i915_private *dev_priv) |
Line 4488... | Line 4506... | ||
4488 | if (IS_CHERRYVIEW(dev)) |
4506 | { |
4489 | valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); |
4507 | mutex_lock(&dev_priv->rps.hw_lock); |
4490 | else if (IS_VALLEYVIEW(dev)) |
4508 | if (dev_priv->rps.enabled) { |
4491 | vlv_set_rps_idle(dev_priv); |
4509 | if (dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) |
4492 | else |
4510 | gen6_rps_reset_ei(dev_priv); |
4493 | gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); |
4511 | I915_WRITE(GEN6_PMINTRMSK, |
4494 | dev_priv->rps.last_adj = 0; |
4512 | gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); |
- | 4513 | } |
|
4495 | } |
4514 | mutex_unlock(&dev_priv->rps.hw_lock); |
4496 | mutex_unlock(&dev_priv->rps.hw_lock); |
4515 | } |
- | 4516 | ||
- | 4517 | void gen6_rps_idle(struct drm_i915_private *dev_priv) |
|
- | 4518 | { |
|
- | 4519 | struct drm_device *dev = dev_priv->dev; |
|
- | 4520 | ||
4497 | } |
4521 | mutex_lock(&dev_priv->rps.hw_lock); |
Line 4498... | Line 4522... | ||
4498 | 4522 | if (dev_priv->rps.enabled) { |
|
- | 4523 | if (IS_VALLEYVIEW(dev)) |
|
- | 4524 | vlv_set_rps_idle(dev_priv); |
|
4499 | void gen6_rps_boost(struct drm_i915_private *dev_priv) |
4525 | else |
4500 | { |
4526 | gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq); |
- | 4527 | dev_priv->rps.last_adj = 0; |
|
4501 | struct drm_device *dev = dev_priv->dev; |
4528 | I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); |
4502 | 4529 | } |
|
4503 | mutex_lock(&dev_priv->rps.hw_lock); |
4530 | mutex_unlock(&dev_priv->rps.hw_lock); |
4504 | if (dev_priv->rps.enabled) { |
4531 | |
- | 4532 | spin_lock(&dev_priv->rps.client_lock); |
|
Line 4505... | Line 4533... | ||
4505 | if (IS_VALLEYVIEW(dev)) |
4533 | while (!list_empty(&dev_priv->rps.clients)) |
4506 | valleyview_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); |
4534 | list_del_init(dev_priv->rps.clients.next); |
- | 4535 | spin_unlock(&dev_priv->rps.client_lock); |
|
- | 4536 | } |
|
4507 | else |
4537 | |
Line 4508... | Line 4538... | ||
4508 | gen6_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); |
4538 | void gen6_rps_boost(struct drm_i915_private *dev_priv, |
- | 4539 | struct intel_rps_client *rps, |
|
- | 4540 | unsigned long submitted) |
|
- | 4541 | { |
|
- | 4542 | /* This is intentionally racy! We peek at the state here, then |
|
4509 | dev_priv->rps.last_adj = 0; |
4543 | * validate inside the RPS worker. |
- | 4544 | */ |
|
- | 4545 | if (!(dev_priv->mm.busy && |
|
Line -... | Line 4546... | ||
- | 4546 | dev_priv->rps.enabled && |
|
4510 | } |
4547 | dev_priv->rps.cur_freq < dev_priv->rps.max_freq_softlimit)) |
- | 4548 | return; |
|
- | 4549 | ||
- | 4550 | /* Force a RPS boost (and don't count it against the client) if |
|
- | 4551 | * the GPU is severely congested. |
|
- | 4552 | */ |
|
- | 4553 | if (rps && time_after(jiffies, submitted + DRM_I915_THROTTLE_JIFFIES)) |
|
Line -... | Line 4554... | ||
- | 4554 | rps = NULL; |
|
- | 4555 | ||
- | 4556 | spin_lock(&dev_priv->rps.client_lock); |
|
4511 | mutex_unlock(&dev_priv->rps.hw_lock); |
4557 | if (rps == NULL || list_empty(&rps->link)) { |
- | 4558 | spin_lock_irq(&dev_priv->irq_lock); |
|
4512 | } |
4559 | if (dev_priv->rps.interrupts_enabled) { |
4513 | 4560 | dev_priv->rps.client_boost = true; |
|
Line 4514... | Line 4561... | ||
4514 | void valleyview_set_rps(struct drm_device *dev, u8 val) |
4561 | queue_work(dev_priv->wq, &dev_priv->rps.work); |
4515 | { |
4562 | } |
4516 | struct drm_i915_private *dev_priv = dev->dev_private; |
4563 | spin_unlock_irq(&dev_priv->irq_lock); |
Line 4517... | Line 4564... | ||
4517 | 4564 | ||
- | 4565 | if (rps != NULL) { |
|
4518 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
4566 | list_add(&rps->link, &dev_priv->rps.clients); |
Line 4519... | Line 4567... | ||
4519 | WARN_ON(val > dev_priv->rps.max_freq_softlimit); |
4567 | rps->boosts++; |
4520 | WARN_ON(val < dev_priv->rps.min_freq_softlimit); |
4568 | } else |
4521 | 4569 | dev_priv->rps.boosts++; |
|
Line 4558... | Line 4606... | ||
4558 | { |
4606 | { |
4559 | struct drm_i915_private *dev_priv = dev->dev_private; |
4607 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 4560... | Line 4608... | ||
4560 | 4608 | ||
4561 | /* we're doing forcewake before Disabling RC6, |
4609 | /* we're doing forcewake before Disabling RC6, |
4562 | * This what the BIOS expects when going into suspend */ |
4610 | * This what the BIOS expects when going into suspend */ |
Line 4563... | Line 4611... | ||
4563 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); |
4611 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
Line 4564... | Line 4612... | ||
4564 | 4612 | ||
4565 | I915_WRITE(GEN6_RC_CONTROL, 0); |
4613 | I915_WRITE(GEN6_RC_CONTROL, 0); |
Line 4566... | Line 4614... | ||
4566 | 4614 | ||
4567 | gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); |
4615 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
4568 | } |
4616 | } |
Line 4586... | Line 4634... | ||
4586 | (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off"); |
4634 | (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off"); |
4587 | } |
4635 | } |
Line 4588... | Line 4636... | ||
4588 | 4636 | ||
4589 | static int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6) |
4637 | static int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6) |
4590 | { |
4638 | { |
4591 | /* No RC6 before Ironlake */ |
4639 | /* No RC6 before Ironlake and code is gone for ilk. */ |
4592 | if (INTEL_INFO(dev)->gen < 5) |
- | |
4593 | return 0; |
- | |
4594 | - | ||
4595 | /* RC6 is only on Ironlake mobile not on desktop */ |
- | |
4596 | if (INTEL_INFO(dev)->gen == 5 && !IS_IRONLAKE_M(dev)) |
4640 | if (INTEL_INFO(dev)->gen < 6) |
Line 4597... | Line 4641... | ||
4597 | return 0; |
4641 | return 0; |
4598 | 4642 | ||
4599 | /* Respect the kernel parameter if it is set */ |
4643 | /* Respect the kernel parameter if it is set */ |
Line 4611... | Line 4655... | ||
4611 | enable_rc6 & mask, enable_rc6, mask); |
4655 | enable_rc6 & mask, enable_rc6, mask); |
Line 4612... | Line 4656... | ||
4612 | 4656 | ||
4613 | return enable_rc6 & mask; |
4657 | return enable_rc6 & mask; |
Line 4614... | Line -... | ||
4614 | } |
- | |
4615 | - | ||
4616 | /* Disable RC6 on Ironlake */ |
- | |
4617 | if (INTEL_INFO(dev)->gen == 5) |
- | |
4618 | return 0; |
4658 | } |
4619 | 4659 | ||
Line 4620... | Line 4660... | ||
4620 | if (IS_IVYBRIDGE(dev)) |
4660 | if (IS_IVYBRIDGE(dev)) |
4621 | return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE); |
4661 | return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE); |
Line 4633... | Line 4673... | ||
4633 | struct drm_i915_private *dev_priv = dev->dev_private; |
4673 | struct drm_i915_private *dev_priv = dev->dev_private; |
4634 | uint32_t rp_state_cap; |
4674 | uint32_t rp_state_cap; |
4635 | u32 ddcc_status = 0; |
4675 | u32 ddcc_status = 0; |
4636 | int ret; |
4676 | int ret; |
Line 4637... | Line -... | ||
4637 | - | ||
4638 | rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); |
4677 | |
4639 | /* All of these values are in units of 50MHz */ |
4678 | /* All of these values are in units of 50MHz */ |
4640 | dev_priv->rps.cur_freq = 0; |
4679 | dev_priv->rps.cur_freq = 0; |
- | 4680 | /* static values from HW: RP0 > RP1 > RPn (min_freq) */ |
|
- | 4681 | if (IS_BROXTON(dev)) { |
|
- | 4682 | rp_state_cap = I915_READ(BXT_RP_STATE_CAP); |
|
- | 4683 | dev_priv->rps.rp0_freq = (rp_state_cap >> 16) & 0xff; |
|
- | 4684 | dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff; |
|
- | 4685 | dev_priv->rps.min_freq = (rp_state_cap >> 0) & 0xff; |
|
- | 4686 | } else { |
|
4641 | /* static values from HW: RP0 > RP1 > RPn (min_freq) */ |
4687 | rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); |
4642 | dev_priv->rps.rp0_freq = (rp_state_cap >> 0) & 0xff; |
4688 | dev_priv->rps.rp0_freq = (rp_state_cap >> 0) & 0xff; |
4643 | dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff; |
4689 | dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff; |
- | 4690 | dev_priv->rps.min_freq = (rp_state_cap >> 16) & 0xff; |
|
- | 4691 | } |
|
4644 | dev_priv->rps.min_freq = (rp_state_cap >> 16) & 0xff; |
4692 | |
4645 | /* hw_max = RP0 until we check for overclocking */ |
4693 | /* hw_max = RP0 until we check for overclocking */ |
Line 4646... | Line 4694... | ||
4646 | dev_priv->rps.max_freq = dev_priv->rps.rp0_freq; |
4694 | dev_priv->rps.max_freq = dev_priv->rps.rp0_freq; |
4647 | 4695 | ||
4648 | dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq; |
4696 | dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq; |
4649 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { |
4697 | if (IS_HASWELL(dev) || IS_BROADWELL(dev) || IS_SKYLAKE(dev)) { |
4650 | ret = sandybridge_pcode_read(dev_priv, |
4698 | ret = sandybridge_pcode_read(dev_priv, |
4651 | HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL, |
4699 | HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL, |
4652 | &ddcc_status); |
4700 | &ddcc_status); |
- | 4701 | if (0 == ret) |
|
4653 | if (0 == ret) |
4702 | dev_priv->rps.efficient_freq = |
- | 4703 | clamp_t(u8, |
|
- | 4704 | ((ddcc_status >> 8) & 0xff), |
|
- | 4705 | dev_priv->rps.min_freq, |
|
- | 4706 | dev_priv->rps.max_freq); |
|
- | 4707 | } |
|
- | 4708 | ||
- | 4709 | if (IS_SKYLAKE(dev)) { |
|
- | 4710 | /* Store the frequency values in 16.66 MHZ units, which is |
|
- | 4711 | the natural hardware unit for SKL */ |
|
- | 4712 | dev_priv->rps.rp0_freq *= GEN9_FREQ_SCALER; |
|
- | 4713 | dev_priv->rps.rp1_freq *= GEN9_FREQ_SCALER; |
|
- | 4714 | dev_priv->rps.min_freq *= GEN9_FREQ_SCALER; |
|
4654 | dev_priv->rps.efficient_freq = |
4715 | dev_priv->rps.max_freq *= GEN9_FREQ_SCALER; |
Line -... | Line 4716... | ||
- | 4716 | dev_priv->rps.efficient_freq *= GEN9_FREQ_SCALER; |
|
- | 4717 | } |
|
4655 | (ddcc_status >> 8) & 0xff; |
4718 | |
4656 | } |
4719 | dev_priv->rps.idle_freq = dev_priv->rps.min_freq; |
4657 | 4720 | ||
Line 4658... | Line 4721... | ||
4658 | /* Preserve min/max settings in case of re-init */ |
4721 | /* Preserve min/max settings in case of re-init */ |
4659 | if (dev_priv->rps.max_freq_softlimit == 0) |
4722 | if (dev_priv->rps.max_freq_softlimit == 0) |
4660 | dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq; |
4723 | dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq; |
4661 | 4724 | ||
4662 | if (dev_priv->rps.min_freq_softlimit == 0) { |
4725 | if (dev_priv->rps.min_freq_softlimit == 0) { |
4663 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
4726 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
4664 | dev_priv->rps.min_freq_softlimit = |
4727 | dev_priv->rps.min_freq_softlimit = |
4665 | /* max(RPe, 450 MHz) */ |
4728 | max_t(int, dev_priv->rps.efficient_freq, |
4666 | max(dev_priv->rps.efficient_freq, (u8) 9); |
4729 | intel_freq_opcode(dev_priv, 450)); |
4667 | else |
4730 | else |
Line -... | Line 4731... | ||
- | 4731 | dev_priv->rps.min_freq_softlimit = |
|
4668 | dev_priv->rps.min_freq_softlimit = |
4732 | dev_priv->rps.min_freq; |
4669 | dev_priv->rps.min_freq; |
4733 | } |
4670 | } |
4734 | } |
- | 4735 | ||
- | 4736 | /* See the Gen9_GT_PM_Programming_Guide doc for the below */ |
|
- | 4737 | static void gen9_enable_rps(struct drm_device *dev) |
|
- | 4738 | { |
|
- | 4739 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 4740 | ||
- | 4741 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
|
- | 4742 | ||
- | 4743 | gen6_init_rps_frequencies(dev); |
|
- | 4744 | ||
- | 4745 | /* WaGsvDisableTurbo: Workaround to disable turbo on BXT A* */ |
|
- | 4746 | if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) { |
|
- | 4747 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
|
- | 4748 | return; |
|
- | 4749 | } |
|
- | 4750 | ||
- | 4751 | /* Program defaults and thresholds for RPS*/ |
|
- | 4752 | I915_WRITE(GEN6_RC_VIDEO_FREQ, |
|
- | 4753 | GEN9_FREQUENCY(dev_priv->rps.rp1_freq)); |
|
- | 4754 | ||
- | 4755 | /* 1 second timeout*/ |
|
- | 4756 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, |
|
- | 4757 | GT_INTERVAL_FROM_US(dev_priv, 1000000)); |
|
- | 4758 | ||
- | 4759 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 0xa); |
|
- | 4760 | ||
- | 4761 | /* Leaning on the below call to gen6_set_rps to program/setup the |
|
- | 4762 | * Up/Down EI & threshold registers, as well as the RP_CONTROL, |
|
- | 4763 | * RP_INTERRUPT_LIMITS & RPNSWREQ registers */ |
|
- | 4764 | dev_priv->rps.power = HIGH_POWER; /* force a reset */ |
|
- | 4765 | gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); |
|
- | 4766 | ||
- | 4767 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
|
4671 | } |
4768 | } |
4672 | 4769 | ||
4673 | static void gen9_enable_rps(struct drm_device *dev) |
4770 | static void gen9_enable_rc6(struct drm_device *dev) |
Line 4674... | Line 4771... | ||
4674 | { |
4771 | { |
4675 | struct drm_i915_private *dev_priv = dev->dev_private; |
4772 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 4676... | Line 4773... | ||
4676 | struct intel_engine_cs *ring; |
4773 | struct intel_engine_cs *ring; |
4677 | uint32_t rc6_mask = 0; |
4774 | uint32_t rc6_mask = 0; |
4678 | int unused; |
4775 | int unused; |
Line 4679... | Line 4776... | ||
4679 | 4776 | ||
4680 | /* 1a: Software RC state - RC0 */ |
4777 | /* 1a: Software RC state - RC0 */ |
Line 4681... | Line 4778... | ||
4681 | I915_WRITE(GEN6_RC_STATE, 0); |
4778 | I915_WRITE(GEN6_RC_STATE, 0); |
- | 4779 | ||
- | 4780 | /* 1b: Get forcewake during program sequence. Although the driver |
|
- | 4781 | * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ |
|
- | 4782 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
|
- | 4783 | ||
4682 | 4784 | /* 2a: Disable RC states. */ |
|
4683 | /* 1b: Get forcewake during program sequence. Although the driver |
4785 | I915_WRITE(GEN6_RC_CONTROL, 0); |
4684 | * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ |
4786 | |
4685 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); |
4787 | /* 2b: Program RC6 thresholds.*/ |
4686 | 4788 | ||
- | 4789 | /* WaRsDoubleRc6WrlWithCoarsePowerGating: Doubling WRL only when CPG is enabled */ |
|
- | 4790 | if (IS_SKYLAKE(dev)) |
|
- | 4791 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16); |
|
- | 4792 | else |
|
4687 | /* 2a: Disable RC states. */ |
4793 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16); |
- | 4794 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ |
|
- | 4795 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ |
|
- | 4796 | for_each_ring(ring, dev_priv, unused) |
|
4688 | I915_WRITE(GEN6_RC_CONTROL, 0); |
4797 | I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); |
Line 4689... | Line 4798... | ||
4689 | 4798 | ||
4690 | /* 2b: Program RC6 thresholds.*/ |
4799 | if (HAS_GUC_UCODE(dev)) |
4691 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16); |
4800 | I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA); |
4692 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ |
4801 | |
4693 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ |
4802 | I915_WRITE(GEN6_RC_SLEEP, 0); |
- | 4803 | ||
- | 4804 | /* 2c: Program Coarse Power Gating Policies. */ |
|
- | 4805 | I915_WRITE(GEN9_MEDIA_PG_IDLE_HYSTERESIS, 25); |
|
- | 4806 | I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 25); |
|
- | 4807 | ||
- | 4808 | /* 3a: Enable RC6 */ |
|
- | 4809 | if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE) |
|
- | 4810 | rc6_mask = GEN6_RC_CTL_RC6_ENABLE; |
|
- | 4811 | DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? |
|
4694 | for_each_ring(ring, dev_priv, unused) |
4812 | "on" : "off"); |
4695 | I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); |
4813 | /* WaRsUseTimeoutMode */ |
4696 | I915_WRITE(GEN6_RC_SLEEP, 0); |
4814 | if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_D0) || |
- | 4815 | (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0)) { |
|
Line -... | Line 4816... | ||
- | 4816 | I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us */ |
|
- | 4817 | I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | |
|
- | 4818 | GEN7_RC_CTL_TO_MODE | |
|
- | 4819 | rc6_mask); |
|
- | 4820 | } else { |
|
- | 4821 | I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */ |
|
- | 4822 | I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | |
|
- | 4823 | GEN6_RC_CTL_EI_MODE(1) | |
|
- | 4824 | rc6_mask); |
|
- | 4825 | } |
|
- | 4826 | ||
4697 | I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */ |
4827 | /* |
Line 4698... | Line 4828... | ||
4698 | 4828 | * 3b: Enable Coarse Power Gating only when RC6 is enabled. |
|
Line 4699... | Line 4829... | ||
4699 | /* 3a: Enable RC6 */ |
4829 | * WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6. |
4700 | if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE) |
4830 | */ |
Line 4719... | Line 4849... | ||
4719 | /* 1a: Software RC state - RC0 */ |
4849 | /* 1a: Software RC state - RC0 */ |
4720 | I915_WRITE(GEN6_RC_STATE, 0); |
4850 | I915_WRITE(GEN6_RC_STATE, 0); |
Line 4721... | Line 4851... | ||
4721 | 4851 | ||
4722 | /* 1c & 1d: Get forcewake during program sequence. Although the driver |
4852 | /* 1c & 1d: Get forcewake during program sequence. Although the driver |
4723 | * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ |
4853 | * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ |
Line 4724... | Line 4854... | ||
4724 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); |
4854 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
4725 | 4855 | ||
Line 4726... | Line 4856... | ||
4726 | /* 2a: Disable RC states. */ |
4856 | /* 2a: Disable RC states. */ |
Line 4784... | Line 4914... | ||
4784 | GEN6_RP_DOWN_IDLE_AVG); |
4914 | GEN6_RP_DOWN_IDLE_AVG); |
Line 4785... | Line 4915... | ||
4785 | 4915 | ||
Line 4786... | Line 4916... | ||
4786 | /* 6: Ring frequency + overclocking (our driver does this later */ |
4916 | /* 6: Ring frequency + overclocking (our driver does this later */ |
4787 | 4917 | ||
Line 4788... | Line 4918... | ||
4788 | dev_priv->rps.power = HIGH_POWER; /* force a reset */ |
4918 | dev_priv->rps.power = HIGH_POWER; /* force a reset */ |
4789 | gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); |
4919 | gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq); |
Line 4790... | Line 4920... | ||
4790 | 4920 | ||
4791 | gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); |
4921 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
4792 | } |
4922 | } |
Line 4814... | Line 4944... | ||
4814 | if ((gtfifodbg = I915_READ(GTFIFODBG))) { |
4944 | if ((gtfifodbg = I915_READ(GTFIFODBG))) { |
4815 | DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg); |
4945 | DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg); |
4816 | I915_WRITE(GTFIFODBG, gtfifodbg); |
4946 | I915_WRITE(GTFIFODBG, gtfifodbg); |
4817 | } |
4947 | } |
Line 4818... | Line 4948... | ||
4818 | 4948 | ||
Line 4819... | Line 4949... | ||
4819 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); |
4949 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
4820 | 4950 | ||
Line 4821... | Line 4951... | ||
4821 | /* Initialize rps frequencies */ |
4951 | /* Initialize rps frequencies */ |
Line 4878... | Line 5008... | ||
4878 | (pcu_mbox & 0xff) * 50); |
5008 | (pcu_mbox & 0xff) * 50); |
4879 | dev_priv->rps.max_freq = pcu_mbox & 0xff; |
5009 | dev_priv->rps.max_freq = pcu_mbox & 0xff; |
4880 | } |
5010 | } |
Line 4881... | Line 5011... | ||
4881 | 5011 | ||
4882 | dev_priv->rps.power = HIGH_POWER; /* force a reset */ |
5012 | dev_priv->rps.power = HIGH_POWER; /* force a reset */ |
Line 4883... | Line 5013... | ||
4883 | gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); |
5013 | gen6_set_rps(dev_priv->dev, dev_priv->rps.idle_freq); |
4884 | 5014 | ||
4885 | rc6vids = 0; |
5015 | rc6vids = 0; |
4886 | ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids); |
5016 | ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids); |
Line 4894... | Line 5024... | ||
4894 | ret = sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_RC6VIDS, rc6vids); |
5024 | ret = sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_RC6VIDS, rc6vids); |
4895 | if (ret) |
5025 | if (ret) |
4896 | DRM_ERROR("Couldn't fix incorrect rc6 voltage\n"); |
5026 | DRM_ERROR("Couldn't fix incorrect rc6 voltage\n"); |
4897 | } |
5027 | } |
Line 4898... | Line 5028... | ||
4898 | 5028 | ||
4899 | gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); |
5029 | intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
Line 4900... | Line 5030... | ||
4900 | } |
5030 | } |
4901 | 5031 | ||
4902 | static void __gen6_update_ring_freq(struct drm_device *dev) |
5032 | static void __gen6_update_ring_freq(struct drm_device *dev) |
4903 | { |
5033 | { |
4904 | struct drm_i915_private *dev_priv = dev->dev_private; |
5034 | struct drm_i915_private *dev_priv = dev->dev_private; |
4905 | int min_freq = 15; |
5035 | int min_freq = 15; |
- | 5036 | unsigned int gpu_freq; |
|
4906 | unsigned int gpu_freq; |
5037 | unsigned int max_ia_freq, min_ring_freq; |
4907 | unsigned int max_ia_freq, min_ring_freq; |
5038 | unsigned int max_gpu_freq, min_gpu_freq; |
Line 4908... | Line 5039... | ||
4908 | int scaling_factor = 180; |
5039 | int scaling_factor = 180; |
Line 4922... | Line 5053... | ||
4922 | 5053 | ||
4923 | min_ring_freq = I915_READ(DCLK) & 0xf; |
5054 | min_ring_freq = I915_READ(DCLK) & 0xf; |
4924 | /* convert DDR frequency from units of 266.6MHz to bandwidth */ |
5055 | /* convert DDR frequency from units of 266.6MHz to bandwidth */ |
Line -... | Line 5056... | ||
- | 5056 | min_ring_freq = mult_frac(min_ring_freq, 8, 3); |
|
- | 5057 | ||
- | 5058 | if (IS_SKYLAKE(dev)) { |
|
- | 5059 | /* Convert GT frequency to 50 HZ units */ |
|
- | 5060 | min_gpu_freq = dev_priv->rps.min_freq / GEN9_FREQ_SCALER; |
|
- | 5061 | max_gpu_freq = dev_priv->rps.max_freq / GEN9_FREQ_SCALER; |
|
- | 5062 | } else { |
|
- | 5063 | min_gpu_freq = dev_priv->rps.min_freq; |
|
- | 5064 | max_gpu_freq = dev_priv->rps.max_freq; |
|
4925 | min_ring_freq = mult_frac(min_ring_freq, 8, 3); |
5065 | } |
4926 | 5066 | ||
4927 | /* |
5067 | /* |
4928 | * For each potential GPU frequency, load a ring frequency we'd like |
5068 | * For each potential GPU frequency, load a ring frequency we'd like |
4929 | * to use for memory access. We do this by specifying the IA frequency |
5069 | * to use for memory access. We do this by specifying the IA frequency |
4930 | * the PCU should use as a reference to determine the ring frequency. |
5070 | * the PCU should use as a reference to determine the ring frequency. |
4931 | */ |
- | |
4932 | for (gpu_freq = dev_priv->rps.max_freq; gpu_freq >= dev_priv->rps.min_freq; |
5071 | */ |
4933 | gpu_freq--) { |
5072 | for (gpu_freq = max_gpu_freq; gpu_freq >= min_gpu_freq; gpu_freq--) { |
Line -... | Line 5073... | ||
- | 5073 | int diff = max_gpu_freq - gpu_freq; |
|
- | 5074 | unsigned int ia_freq = 0, ring_freq = 0; |
|
- | 5075 | ||
- | 5076 | if (IS_SKYLAKE(dev)) { |
|
- | 5077 | /* |
|
- | 5078 | * ring_freq = 2 * GT. ring_freq is in 100MHz units |
|
4934 | int diff = dev_priv->rps.max_freq - gpu_freq; |
5079 | * No floor required for ring frequency on SKL. |
4935 | unsigned int ia_freq = 0, ring_freq = 0; |
5080 | */ |
4936 | 5081 | ring_freq = gpu_freq; |
|
4937 | if (INTEL_INFO(dev)->gen >= 8) { |
5082 | } else if (INTEL_INFO(dev)->gen >= 8) { |
4938 | /* max(2 * GT, DDR). NB: GT is 50MHz units */ |
5083 | /* max(2 * GT, DDR). NB: GT is 50MHz units */ |
4939 | ring_freq = max(min_ring_freq, gpu_freq); |
5084 | ring_freq = max(min_ring_freq, gpu_freq); |
Line 4966... | Line 5111... | ||
4966 | 5111 | ||
4967 | void gen6_update_ring_freq(struct drm_device *dev) |
5112 | void gen6_update_ring_freq(struct drm_device *dev) |
4968 | { |
5113 | { |
Line 4969... | Line 5114... | ||
4969 | struct drm_i915_private *dev_priv = dev->dev_private; |
5114 | struct drm_i915_private *dev_priv = dev->dev_private; |
4970 | 5115 | ||
Line 4971... | Line 5116... | ||
4971 | if (INTEL_INFO(dev)->gen < 6 || IS_VALLEYVIEW(dev)) |
5116 | if (!HAS_CORE_RING_FREQ(dev)) |
4972 | return; |
5117 | return; |
4973 | 5118 | ||
4974 | mutex_lock(&dev_priv->rps.hw_lock); |
5119 | mutex_lock(&dev_priv->rps.hw_lock); |
Line 4975... | Line 5120... | ||
4975 | __gen6_update_ring_freq(dev); |
5120 | __gen6_update_ring_freq(dev); |
4976 | mutex_unlock(&dev_priv->rps.hw_lock); |
5121 | mutex_unlock(&dev_priv->rps.hw_lock); |
- | 5122 | } |
|
4977 | } |
5123 | |
Line 4978... | Line 5124... | ||
4978 | 5124 | static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv) |
|
- | 5125 | { |
|
- | 5126 | struct drm_device *dev = dev_priv->dev; |
|
- | 5127 | u32 val, rp0; |
|
- | 5128 | ||
- | 5129 | val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); |
|
- | 5130 | ||
- | 5131 | switch (INTEL_INFO(dev)->eu_total) { |
|
- | 5132 | case 8: |
|
- | 5133 | /* (2 * 4) config */ |
|
- | 5134 | rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT); |
|
- | 5135 | break; |
|
- | 5136 | case 12: |
|
- | 5137 | /* (2 * 6) config */ |
|
- | 5138 | rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT); |
|
4979 | static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv) |
5139 | break; |
- | 5140 | case 16: |
|
- | 5141 | /* (2 * 8) config */ |
|
- | 5142 | default: |
|
- | 5143 | /* Setting (2 * 8) Min RP0 for any other combination */ |
|
Line 4980... | Line 5144... | ||
4980 | { |
5144 | rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT); |
4981 | u32 val, rp0; |
5145 | break; |
Line 4982... | Line 5146... | ||
4982 | 5146 | } |
|
Line 4998... | Line 5162... | ||
4998 | 5162 | ||
4999 | static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv) |
5163 | static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv) |
5000 | { |
5164 | { |
Line 5001... | Line 5165... | ||
5001 | u32 val, rp1; |
5165 | u32 val, rp1; |
5002 | 5166 | ||
Line 5003... | Line 5167... | ||
5003 | val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); |
5167 | val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); |
5004 | rp1 = (val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) & PUNIT_GPU_STATUS_MAX_FREQ_MASK; |
5168 | rp1 = (val & FB_GFX_FREQ_FUSE_MASK); |
Line 5005... | Line -... | ||
5005 | - | ||
5006 | return rp1; |
- | |
5007 | } |
- | |
5008 | - | ||
5009 | static int cherryview_rps_min_freq(struct drm_i915_private *dev_priv) |
- | |
5010 | { |
- | |
5011 | u32 val, rpn; |
- | |
5012 | - | ||
5013 | val = vlv_punit_read(dev_priv, PUNIT_GPU_STATUS_REG); |
- | |
5014 | rpn = (val >> PUNIT_GPU_STATIS_GFX_MIN_FREQ_SHIFT) & PUNIT_GPU_STATUS_GFX_MIN_FREQ_MASK; |
5169 | |
5015 | return rpn; |
5170 | return rp1; |
5016 | } |
5171 | } |
Line 5017... | Line 5172... | ||
5017 | 5172 | ||
Line 5180... | Line 5335... | ||
5180 | DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); |
5335 | DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); |
Line 5181... | Line 5336... | ||
5181 | 5336 | ||
5182 | dev_priv->rps.max_freq = valleyview_rps_max_freq(dev_priv); |
5337 | dev_priv->rps.max_freq = valleyview_rps_max_freq(dev_priv); |
5183 | dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; |
5338 | dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; |
5184 | DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", |
5339 | DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", |
5185 | vlv_gpu_freq(dev_priv, dev_priv->rps.max_freq), |
5340 | intel_gpu_freq(dev_priv, dev_priv->rps.max_freq), |
Line 5186... | Line 5341... | ||
5186 | dev_priv->rps.max_freq); |
5341 | dev_priv->rps.max_freq); |
5187 | 5342 | ||
5188 | dev_priv->rps.efficient_freq = valleyview_rps_rpe_freq(dev_priv); |
5343 | dev_priv->rps.efficient_freq = valleyview_rps_rpe_freq(dev_priv); |
5189 | DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", |
5344 | DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", |
Line 5190... | Line 5345... | ||
5190 | vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), |
5345 | intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), |
5191 | dev_priv->rps.efficient_freq); |
5346 | dev_priv->rps.efficient_freq); |
5192 | 5347 | ||
5193 | dev_priv->rps.rp1_freq = valleyview_rps_guar_freq(dev_priv); |
5348 | dev_priv->rps.rp1_freq = valleyview_rps_guar_freq(dev_priv); |
Line 5194... | Line 5349... | ||
5194 | DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n", |
5349 | DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n", |
5195 | vlv_gpu_freq(dev_priv, dev_priv->rps.rp1_freq), |
5350 | intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq), |
5196 | dev_priv->rps.rp1_freq); |
5351 | dev_priv->rps.rp1_freq); |
5197 | 5352 | ||
Line -... | Line 5353... | ||
- | 5353 | dev_priv->rps.min_freq = valleyview_rps_min_freq(dev_priv); |
|
- | 5354 | DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", |
|
5198 | dev_priv->rps.min_freq = valleyview_rps_min_freq(dev_priv); |
5355 | intel_gpu_freq(dev_priv, dev_priv->rps.min_freq), |
5199 | DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", |
5356 | dev_priv->rps.min_freq); |
5200 | vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq), |
5357 | |
Line 5201... | Line 5358... | ||
5201 | dev_priv->rps.min_freq); |
5358 | dev_priv->rps.idle_freq = dev_priv->rps.min_freq; |
Line 5217... | Line 5374... | ||
5217 | 5374 | ||
Line 5218... | Line 5375... | ||
5218 | cherryview_setup_pctx(dev); |
5375 | cherryview_setup_pctx(dev); |
Line 5219... | Line 5376... | ||
5219 | 5376 | ||
5220 | mutex_lock(&dev_priv->rps.hw_lock); |
5377 | mutex_lock(&dev_priv->rps.hw_lock); |
5221 | 5378 | ||
Line 5222... | Line 5379... | ||
5222 | mutex_lock(&dev_priv->dpio_lock); |
5379 | mutex_lock(&dev_priv->sb_lock); |
5223 | val = vlv_cck_read(dev_priv, CCK_FUSE_REG); |
- | |
5224 | mutex_unlock(&dev_priv->dpio_lock); |
- | |
5225 | - | ||
5226 | switch ((val >> 2) & 0x7) { |
- | |
5227 | case 0: |
- | |
5228 | case 1: |
- | |
5229 | dev_priv->rps.cz_freq = 200; |
- | |
5230 | dev_priv->mem_freq = 1600; |
- | |
5231 | break; |
- | |
5232 | case 2: |
5380 | val = vlv_cck_read(dev_priv, CCK_FUSE_REG); |
5233 | dev_priv->rps.cz_freq = 267; |
- | |
5234 | dev_priv->mem_freq = 1600; |
5381 | mutex_unlock(&dev_priv->sb_lock); |
5235 | break; |
5382 | |
5236 | case 3: |
- | |
5237 | dev_priv->rps.cz_freq = 333; |
- | |
5238 | dev_priv->mem_freq = 2000; |
- | |
5239 | break; |
- | |
5240 | case 4: |
5383 | switch ((val >> 2) & 0x7) { |
5241 | dev_priv->rps.cz_freq = 320; |
- | |
5242 | dev_priv->mem_freq = 1600; |
5384 | case 3: |
5243 | break; |
5385 | dev_priv->mem_freq = 2000; |
5244 | case 5: |
5386 | break; |
5245 | dev_priv->rps.cz_freq = 400; |
5387 | default: |
Line 5246... | Line 5388... | ||
5246 | dev_priv->mem_freq = 1600; |
5388 | dev_priv->mem_freq = 1600; |
5247 | break; |
5389 | break; |
5248 | } |
5390 | } |
5249 | DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); |
5391 | DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); |
5250 | 5392 | ||
Line 5251... | Line 5393... | ||
5251 | dev_priv->rps.max_freq = cherryview_rps_max_freq(dev_priv); |
5393 | dev_priv->rps.max_freq = cherryview_rps_max_freq(dev_priv); |
5252 | dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; |
5394 | dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; |
5253 | DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", |
5395 | DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", |
5254 | vlv_gpu_freq(dev_priv, dev_priv->rps.max_freq), |
5396 | intel_gpu_freq(dev_priv, dev_priv->rps.max_freq), |
Line 5255... | Line 5397... | ||
5255 | dev_priv->rps.max_freq); |
5397 | dev_priv->rps.max_freq); |
5256 | 5398 | ||
5257 | dev_priv->rps.efficient_freq = cherryview_rps_rpe_freq(dev_priv); |
5399 | dev_priv->rps.efficient_freq = cherryview_rps_rpe_freq(dev_priv); |
5258 | DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", |
5400 | DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", |
Line -... | Line 5401... | ||
- | 5401 | intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), |
|
5259 | vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), |
5402 | dev_priv->rps.efficient_freq); |
5260 | dev_priv->rps.efficient_freq); |
5403 | |
5261 | 5404 | dev_priv->rps.rp1_freq = cherryview_rps_guar_freq(dev_priv); |
|
5262 | dev_priv->rps.rp1_freq = cherryview_rps_guar_freq(dev_priv); |
5405 | DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n", |
Line 5263... | Line 5406... | ||
5263 | DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n", |
5406 | intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq), |
5264 | vlv_gpu_freq(dev_priv, dev_priv->rps.rp1_freq), |
5407 | dev_priv->rps.rp1_freq); |
5265 | dev_priv->rps.rp1_freq); |
5408 | |
5266 | 5409 | /* PUnit validated range is only [RPe, RP0] */ |
|
5267 | dev_priv->rps.min_freq = cherryview_rps_min_freq(dev_priv); |
5410 | dev_priv->rps.min_freq = dev_priv->rps.efficient_freq; |
Line -... | Line 5411... | ||
- | 5411 | DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", |
|
- | 5412 | intel_gpu_freq(dev_priv, dev_priv->rps.min_freq), |
|
5268 | DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", |
5413 | dev_priv->rps.min_freq); |
5269 | vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq), |
5414 | |
5270 | dev_priv->rps.min_freq); |
5415 | WARN_ONCE((dev_priv->rps.max_freq | |
Line 5271... | Line 5416... | ||
5271 | 5416 | dev_priv->rps.efficient_freq | |
|
Line 5308... | Line 5453... | ||
5308 | 5453 | ||
Line 5309... | Line 5454... | ||
5309 | cherryview_check_pctx(dev_priv); |
5454 | cherryview_check_pctx(dev_priv); |
5310 | 5455 | ||
5311 | /* 1a & 1b: Get forcewake during program sequence. Although the driver |
5456 | /* 1a & 1b: Get forcewake during program sequence. Although the driver |
- | 5457 | * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ |
|
- | 5458 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
|
- | 5459 | ||
Line 5312... | Line 5460... | ||
5312 | * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ |
5460 | /* Disable RC states. */ |
5313 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); |
5461 | I915_WRITE(GEN6_RC_CONTROL, 0); |
5314 | 5462 | ||
5315 | /* 2a: Program RC6 thresholds.*/ |
5463 | /* 2a: Program RC6 thresholds.*/ |
Line 5316... | Line 5464... | ||
5316 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); |
5464 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); |
5317 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ |
5465 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ |
5318 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ |
5466 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ |
Line -... | Line 5467... | ||
- | 5467 | ||
5319 | 5468 | for_each_ring(ring, dev_priv, i) |
|
Line 5320... | Line 5469... | ||
5320 | for_each_ring(ring, dev_priv, i) |
5469 | I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); |
5321 | I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); |
5470 | I915_WRITE(GEN6_RC_SLEEP, 0); |
5322 | I915_WRITE(GEN6_RC_SLEEP, 0); |
5471 | |
5323 | 5472 | /* TO threshold set to 500 us ( 0x186 * 1.28 us) */ |
|
Line 5333... | Line 5482... | ||
5333 | pcbr = I915_READ(VLV_PCBR); |
5482 | pcbr = I915_READ(VLV_PCBR); |
Line 5334... | Line 5483... | ||
5334 | 5483 | ||
5335 | /* 3: Enable RC6 */ |
5484 | /* 3: Enable RC6 */ |
5336 | if ((intel_enable_rc6(dev) & INTEL_RC6_ENABLE) && |
5485 | if ((intel_enable_rc6(dev) & INTEL_RC6_ENABLE) && |
5337 | (pcbr >> VLV_PCBR_ADDR_SHIFT)) |
5486 | (pcbr >> VLV_PCBR_ADDR_SHIFT)) |
Line 5338... | Line 5487... | ||
5338 | rc6_mode = GEN6_RC_CTL_EI_MODE(1); |
5487 | rc6_mode = GEN7_RC_CTL_TO_MODE; |
Line 5339... | Line 5488... | ||
5339 | 5488 | ||
- | 5489 | I915_WRITE(GEN6_RC_CONTROL, rc6_mode); |
|
5340 | I915_WRITE(GEN6_RC_CONTROL, rc6_mode); |
5490 | |
5341 | 5491 | /* 4 Program defaults and thresholds for RPS*/ |
|
5342 | /* 4 Program defaults and thresholds for RPS*/ |
5492 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); |
5343 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); |
5493 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); |
Line 5344... | Line 5494... | ||
5344 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); |
5494 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); |
Line 5345... | Line -... | ||
5345 | I915_WRITE(GEN6_RP_UP_EI, 66000); |
- | |
5346 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); |
- | |
5347 | - | ||
5348 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
- | |
5349 | 5495 | I915_WRITE(GEN6_RP_UP_EI, 66000); |
|
5350 | /* WaDisablePwrmtrEvent:chv (pre-production hw) */ |
5496 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); |
5351 | I915_WRITE(0xA80C, I915_READ(0xA80C) & 0x00ffffff); |
5497 | |
5352 | I915_WRITE(0xA810, I915_READ(0xA810) & 0xffffff00); |
5498 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
5353 | 5499 | ||
5354 | /* 5: Enable RPS */ |
5500 | /* 5: Enable RPS */ |
5355 | I915_WRITE(GEN6_RP_CONTROL, |
5501 | I915_WRITE(GEN6_RP_CONTROL, |
Line -... | Line 5502... | ||
- | 5502 | GEN6_RP_MEDIA_HW_NORMAL_MODE | |
|
- | 5503 | GEN6_RP_MEDIA_IS_GFX | |
|
- | 5504 | GEN6_RP_ENABLE | |
|
- | 5505 | GEN6_RP_UP_BUSY_AVG | |
|
- | 5506 | GEN6_RP_DOWN_IDLE_AVG); |
|
- | 5507 | ||
5356 | GEN6_RP_MEDIA_HW_NORMAL_MODE | |
5508 | /* Setting Fixed Bias */ |
Line 5357... | Line 5509... | ||
5357 | GEN6_RP_MEDIA_IS_GFX | /* WaSetMaskForGfxBusyness:chv (pre-production hw ?) */ |
5509 | val = VLV_OVERRIDE_EN | |
5358 | GEN6_RP_ENABLE | |
5510 | VLV_SOC_TDP_EN | |
Line 5359... | Line 5511... | ||
5359 | GEN6_RP_UP_BUSY_AVG | |
5511 | CHV_BIAS_CPU_50_SOC_50; |
5360 | GEN6_RP_DOWN_IDLE_AVG); |
5512 | vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val); |
Line 5361... | Line 5513... | ||
5361 | 5513 | ||
5362 | val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); |
5514 | val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); |
5363 | 5515 | ||
5364 | /* RPS code assumes GPLL is used */ |
5516 | /* RPS code assumes GPLL is used */ |
Line 5365... | Line 5517... | ||
5365 | WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n"); |
5517 | WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n"); |
5366 | 5518 | ||
5367 | DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & GPLLENABLE ? "yes" : "no"); |
5519 | DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE)); |
Line 5368... | Line 5520... | ||
5368 | DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); |
5520 | DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); |
Line 5369... | Line 5521... | ||
5369 | 5521 | ||
5370 | dev_priv->rps.cur_freq = (val >> 8) & 0xff; |
5522 | dev_priv->rps.cur_freq = (val >> 8) & 0xff; |
Line 5371... | Line 5523... | ||
5371 | DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n", |
5523 | DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n", |
5372 | vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq), |
5524 | intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq), |
5373 | dev_priv->rps.cur_freq); |
5525 | dev_priv->rps.cur_freq); |
Line 5397... | Line 5549... | ||
5397 | gtfifodbg); |
5549 | gtfifodbg); |
5398 | I915_WRITE(GTFIFODBG, gtfifodbg); |
5550 | I915_WRITE(GTFIFODBG, gtfifodbg); |
5399 | } |
5551 | } |
Line 5400... | Line 5552... | ||
5400 | 5552 | ||
5401 | /* If VLV, Forcewake all wells, else re-direct to regular path */ |
5553 | /* If VLV, Forcewake all wells, else re-direct to regular path */ |
- | 5554 | intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
|
- | 5555 | ||
- | 5556 | /* Disable RC states. */ |
|
Line -... | Line 5557... | ||
- | 5557 | I915_WRITE(GEN6_RC_CONTROL, 0); |
|
5402 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); |
5558 | |
5403 | 5559 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); |
|
5404 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); |
5560 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); |
5405 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); |
5561 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); |
Line 5406... | Line 5562... | ||
5406 | I915_WRITE(GEN6_RP_UP_EI, 66000); |
5562 | I915_WRITE(GEN6_RP_UP_EI, 66000); |
5407 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); |
- | |
Line 5408... | Line 5563... | ||
5408 | 5563 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); |
|
5409 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
5564 | |
5410 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 0xf4240); |
5565 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
5411 | 5566 | ||
Line 5438... | Line 5593... | ||
5438 | 5593 | ||
Line 5439... | Line 5594... | ||
5439 | intel_print_rc6_info(dev, rc6_mode); |
5594 | intel_print_rc6_info(dev, rc6_mode); |
Line -... | Line 5595... | ||
- | 5595 | ||
- | 5596 | I915_WRITE(GEN6_RC_CONTROL, rc6_mode); |
|
- | 5597 | ||
- | 5598 | /* Setting Fixed Bias */ |
|
- | 5599 | val = VLV_OVERRIDE_EN | |
|
- | 5600 | VLV_SOC_TDP_EN | |
|
5440 | 5601 | VLV_BIAS_CPU_125_SOC_875; |
|
Line 5441... | Line 5602... | ||
5441 | I915_WRITE(GEN6_RC_CONTROL, rc6_mode); |
5602 | vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val); |
5442 | 5603 | ||
Line 5443... | Line 5604... | ||
5443 | val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); |
5604 | val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); |
5444 | 5605 | ||
Line 5445... | Line 5606... | ||
5445 | /* RPS code assumes GPLL is used */ |
5606 | /* RPS code assumes GPLL is used */ |
5446 | WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n"); |
5607 | WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n"); |
5447 | 5608 | ||
5448 | DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & GPLLENABLE ? "yes" : "no"); |
5609 | DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE)); |
Line 5449... | Line 5610... | ||
5449 | DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); |
5610 | DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); |
5450 | 5611 | ||
5451 | dev_priv->rps.cur_freq = (val >> 8) & 0xff; |
5612 | dev_priv->rps.cur_freq = (val >> 8) & 0xff; |
Line 5452... | Line 5613... | ||
5452 | DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n", |
5613 | DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n", |
Line 5453... | Line 5614... | ||
5453 | vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq), |
5614 | intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq), |
5454 | dev_priv->rps.cur_freq); |
- | |
5455 | - | ||
5456 | DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n", |
- | |
5457 | vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), |
- | |
5458 | dev_priv->rps.efficient_freq); |
- | |
5459 | - | ||
5460 | valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq); |
- | |
5461 | - | ||
5462 | gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); |
- | |
5463 | } |
- | |
5464 | - | ||
5465 | void ironlake_teardown_rc6(struct drm_device *dev) |
- | |
5466 | { |
- | |
5467 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
5468 | - | ||
5469 | if (dev_priv->ips.renderctx) { |
- | |
5470 | i915_gem_object_ggtt_unpin(dev_priv->ips.renderctx); |
- | |
5471 | drm_gem_object_unreference(&dev_priv->ips.renderctx->base); |
- | |
5472 | dev_priv->ips.renderctx = NULL; |
- | |
5473 | } |
- | |
5474 | - | ||
5475 | if (dev_priv->ips.pwrctx) { |
- | |
5476 | i915_gem_object_ggtt_unpin(dev_priv->ips.pwrctx); |
- | |
5477 | drm_gem_object_unreference(&dev_priv->ips.pwrctx->base); |
- | |
5478 | dev_priv->ips.pwrctx = NULL; |
- | |
5479 | } |
- | |
5480 | } |
- | |
5481 | - | ||
5482 | static void ironlake_disable_rc6(struct drm_device *dev) |
- | |
5483 | { |
- | |
5484 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
5485 | - | ||
5486 | if (I915_READ(PWRCTXA)) { |
- | |
5487 | /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ |
- | |
5488 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); |
- | |
5489 | wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), |
- | |
5490 | 50); |
- | |
5491 | - | ||
5492 | I915_WRITE(PWRCTXA, 0); |
- | |
5493 | POSTING_READ(PWRCTXA); |
- | |
5494 | - | ||
5495 | I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); |
- | |
5496 | POSTING_READ(RSTDBYCTL); |
- | |
5497 | } |
- | |
5498 | } |
- | |
5499 | - | ||
5500 | static int ironlake_setup_rc6(struct drm_device *dev) |
- | |
5501 | { |
- | |
5502 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
5503 | - | ||
5504 | if (dev_priv->ips.renderctx == NULL) |
- | |
5505 | dev_priv->ips.renderctx = intel_alloc_context_page(dev); |
- | |
5506 | if (!dev_priv->ips.renderctx) |
- | |
5507 | return -ENOMEM; |
- | |
5508 | - | ||
5509 | if (dev_priv->ips.pwrctx == NULL) |
- | |
5510 | dev_priv->ips.pwrctx = intel_alloc_context_page(dev); |
- | |
5511 | if (!dev_priv->ips.pwrctx) { |
- | |
5512 | ironlake_teardown_rc6(dev); |
- | |
5513 | return -ENOMEM; |
- | |
5514 | } |
- | |
5515 | - | ||
5516 | return 0; |
- | |
5517 | } |
- | |
5518 | - | ||
5519 | static void ironlake_enable_rc6(struct drm_device *dev) |
- | |
5520 | { |
- | |
5521 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
5522 | struct intel_engine_cs *ring = &dev_priv->ring[RCS]; |
- | |
5523 | bool was_interruptible; |
- | |
5524 | int ret; |
- | |
5525 | - | ||
5526 | /* rc6 disabled by default due to repeated reports of hanging during |
- | |
5527 | * boot and resume. |
- | |
5528 | */ |
- | |
5529 | if (!intel_enable_rc6(dev)) |
- | |
5530 | return; |
- | |
5531 | - | ||
5532 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); |
- | |
5533 | - | ||
5534 | ret = ironlake_setup_rc6(dev); |
- | |
5535 | if (ret) |
- | |
5536 | return; |
- | |
5537 | - | ||
5538 | was_interruptible = dev_priv->mm.interruptible; |
- | |
5539 | dev_priv->mm.interruptible = false; |
- | |
5540 | - | ||
5541 | /* |
- | |
5542 | * GPU can automatically power down the render unit if given a page |
- | |
5543 | * to save state. |
- | |
5544 | */ |
- | |
5545 | ret = intel_ring_begin(ring, 6); |
- | |
5546 | if (ret) { |
- | |
5547 | ironlake_teardown_rc6(dev); |
- | |
5548 | dev_priv->mm.interruptible = was_interruptible; |
- | |
5549 | return; |
- | |
5550 | } |
- | |
5551 | - | ||
5552 | intel_ring_emit(ring, MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); |
- | |
5553 | intel_ring_emit(ring, MI_SET_CONTEXT); |
- | |
5554 | intel_ring_emit(ring, i915_gem_obj_ggtt_offset(dev_priv->ips.renderctx) | |
- | |
5555 | MI_MM_SPACE_GTT | |
- | |
5556 | MI_SAVE_EXT_STATE_EN | |
- | |
5557 | MI_RESTORE_EXT_STATE_EN | |
- | |
5558 | MI_RESTORE_INHIBIT); |
- | |
5559 | intel_ring_emit(ring, MI_SUSPEND_FLUSH); |
- | |
5560 | intel_ring_emit(ring, MI_NOOP); |
- | |
5561 | intel_ring_emit(ring, MI_FLUSH); |
- | |
5562 | intel_ring_advance(ring); |
- | |
5563 | - | ||
5564 | /* |
- | |
5565 | * Wait for the command parser to advance past MI_SET_CONTEXT. The HW |
- | |
5566 | * does an implicit flush, combined with MI_FLUSH above, it should be |
- | |
5567 | * safe to assume that renderctx is valid |
- | |
5568 | */ |
- | |
5569 | ret = intel_ring_idle(ring); |
- | |
5570 | dev_priv->mm.interruptible = was_interruptible; |
- | |
5571 | if (ret) { |
- | |
5572 | DRM_ERROR("failed to enable ironlake power savings\n"); |
5615 | dev_priv->rps.cur_freq); |
Line 5573... | Line 5616... | ||
5573 | ironlake_teardown_rc6(dev); |
5616 | |
5574 | return; |
5617 | DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n", |
5575 | } |
5618 | intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), |
Line 5693... | Line 5736... | ||
5693 | b = tsfs & TSFS_INTR_MASK; |
5736 | b = tsfs & TSFS_INTR_MASK; |
Line 5694... | Line 5737... | ||
5694 | 5737 | ||
5695 | return ((m * x) / 127) - b; |
5738 | return ((m * x) / 127) - b; |
Line -... | Line 5739... | ||
- | 5739 | } |
|
- | 5740 | ||
- | 5741 | static int _pxvid_to_vd(u8 pxvid) |
|
- | 5742 | { |
|
- | 5743 | if (pxvid == 0) |
|
- | 5744 | return 0; |
|
- | 5745 | ||
- | 5746 | if (pxvid >= 8 && pxvid < 31) |
|
- | 5747 | pxvid = 31; |
|
- | 5748 | ||
- | 5749 | return (pxvid + 2) * 125; |
|
5696 | } |
5750 | } |
5697 | 5751 | ||
5698 | static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) |
5752 | static u32 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) |
5699 | { |
5753 | { |
5700 | struct drm_device *dev = dev_priv->dev; |
5754 | struct drm_device *dev = dev_priv->dev; |
5701 | static const struct v_table { |
- | |
5702 | u16 vd; /* in .1 mil */ |
- | |
5703 | u16 vm; /* in .1 mil */ |
- | |
5704 | } v_table[] = { |
- | |
5705 | { 0, 0, }, |
- | |
5706 | { 375, 0, }, |
- | |
5707 | { 500, 0, }, |
- | |
5708 | { 625, 0, }, |
- | |
5709 | { 750, 0, }, |
- | |
5710 | { 875, 0, }, |
- | |
5711 | { 1000, 0, }, |
- | |
5712 | { 1125, 0, }, |
- | |
5713 | { 4125, 3000, }, |
- | |
5714 | { 4125, 3000, }, |
- | |
5715 | { 4125, 3000, }, |
- | |
5716 | { 4125, 3000, }, |
- | |
5717 | { 4125, 3000, }, |
- | |
5718 | { 4125, 3000, }, |
- | |
5719 | { 4125, 3000, }, |
- | |
5720 | { 4125, 3000, }, |
- | |
5721 | { 4125, 3000, }, |
- | |
5722 | { 4125, 3000, }, |
- | |
5723 | { 4125, 3000, }, |
- | |
5724 | { 4125, 3000, }, |
- | |
5725 | { 4125, 3000, }, |
- | |
5726 | { 4125, 3000, }, |
- | |
5727 | { 4125, 3000, }, |
- | |
5728 | { 4125, 3000, }, |
- | |
5729 | { 4125, 3000, }, |
- | |
5730 | { 4125, 3000, }, |
- | |
5731 | { 4125, 3000, }, |
- | |
5732 | { 4125, 3000, }, |
- | |
5733 | { 4125, 3000, }, |
- | |
5734 | { 4125, 3000, }, |
- | |
5735 | { 4125, 3000, }, |
- | |
5736 | { 4125, 3000, }, |
- | |
5737 | { 4250, 3125, }, |
- | |
5738 | { 4375, 3250, }, |
- | |
5739 | { 4500, 3375, }, |
- | |
5740 | { 4625, 3500, }, |
- | |
5741 | { 4750, 3625, }, |
- | |
5742 | { 4875, 3750, }, |
- | |
5743 | { 5000, 3875, }, |
- | |
5744 | { 5125, 4000, }, |
- | |
5745 | { 5250, 4125, }, |
- | |
5746 | { 5375, 4250, }, |
- | |
5747 | { 5500, 4375, }, |
- | |
5748 | { 5625, 4500, }, |
- | |
5749 | { 5750, 4625, }, |
- | |
5750 | { 5875, 4750, }, |
- | |
5751 | { 6000, 4875, }, |
- | |
5752 | { 6125, 5000, }, |
- | |
5753 | { 6250, 5125, }, |
- | |
5754 | { 6375, 5250, }, |
- | |
5755 | { 6500, 5375, }, |
- | |
5756 | { 6625, 5500, }, |
- | |
5757 | { 6750, 5625, }, |
- | |
5758 | { 6875, 5750, }, |
- | |
5759 | { 7000, 5875, }, |
- | |
5760 | { 7125, 6000, }, |
- | |
5761 | { 7250, 6125, }, |
- | |
5762 | { 7375, 6250, }, |
- | |
5763 | { 7500, 6375, }, |
- | |
5764 | { 7625, 6500, }, |
- | |
5765 | { 7750, 6625, }, |
- | |
5766 | { 7875, 6750, }, |
- | |
5767 | { 8000, 6875, }, |
- | |
5768 | { 8125, 7000, }, |
- | |
5769 | { 8250, 7125, }, |
- | |
5770 | { 8375, 7250, }, |
- | |
5771 | { 8500, 7375, }, |
- | |
5772 | { 8625, 7500, }, |
- | |
5773 | { 8750, 7625, }, |
- | |
5774 | { 8875, 7750, }, |
- | |
5775 | { 9000, 7875, }, |
- | |
5776 | { 9125, 8000, }, |
- | |
5777 | { 9250, 8125, }, |
- | |
5778 | { 9375, 8250, }, |
- | |
5779 | { 9500, 8375, }, |
- | |
5780 | { 9625, 8500, }, |
- | |
5781 | { 9750, 8625, }, |
- | |
5782 | { 9875, 8750, }, |
- | |
5783 | { 10000, 8875, }, |
- | |
5784 | { 10125, 9000, }, |
- | |
5785 | { 10250, 9125, }, |
- | |
5786 | { 10375, 9250, }, |
- | |
5787 | { 10500, 9375, }, |
- | |
5788 | { 10625, 9500, }, |
- | |
5789 | { 10750, 9625, }, |
- | |
5790 | { 10875, 9750, }, |
- | |
5791 | { 11000, 9875, }, |
- | |
5792 | { 11125, 10000, }, |
- | |
5793 | { 11250, 10125, }, |
- | |
5794 | { 11375, 10250, }, |
- | |
5795 | { 11500, 10375, }, |
- | |
5796 | { 11625, 10500, }, |
- | |
5797 | { 11750, 10625, }, |
- | |
5798 | { 11875, 10750, }, |
- | |
5799 | { 12000, 10875, }, |
- | |
5800 | { 12125, 11000, }, |
- | |
5801 | { 12250, 11125, }, |
- | |
5802 | { 12375, 11250, }, |
- | |
5803 | { 12500, 11375, }, |
- | |
5804 | { 12625, 11500, }, |
- | |
5805 | { 12750, 11625, }, |
- | |
5806 | { 12875, 11750, }, |
- | |
5807 | { 13000, 11875, }, |
- | |
5808 | { 13125, 12000, }, |
- | |
5809 | { 13250, 12125, }, |
- | |
5810 | { 13375, 12250, }, |
- | |
5811 | { 13500, 12375, }, |
- | |
5812 | { 13625, 12500, }, |
- | |
5813 | { 13750, 12625, }, |
- | |
5814 | { 13875, 12750, }, |
- | |
5815 | { 14000, 12875, }, |
- | |
5816 | { 14125, 13000, }, |
- | |
5817 | { 14250, 13125, }, |
- | |
5818 | { 14375, 13250, }, |
- | |
5819 | { 14500, 13375, }, |
- | |
5820 | { 14625, 13500, }, |
- | |
5821 | { 14750, 13625, }, |
- | |
5822 | { 14875, 13750, }, |
- | |
5823 | { 15000, 13875, }, |
- | |
5824 | { 15125, 14000, }, |
- | |
5825 | { 15250, 14125, }, |
- | |
5826 | { 15375, 14250, }, |
- | |
5827 | { 15500, 14375, }, |
- | |
5828 | { 15625, 14500, }, |
- | |
5829 | { 15750, 14625, }, |
- | |
5830 | { 15875, 14750, }, |
- | |
5831 | { 16000, 14875, }, |
5755 | const int vd = _pxvid_to_vd(pxvid); |
5832 | { 16125, 15000, }, |
5756 | const int vm = vd - 1125; |
5833 | }; |
5757 | |
5834 | if (INTEL_INFO(dev)->is_mobile) |
5758 | if (INTEL_INFO(dev)->is_mobile) |
5835 | return v_table[pxvid].vm; |
5759 | return vm > 0 ? vm : 0; |
5836 | else |
5760 | |
Line 5837... | Line 5761... | ||
5837 | return v_table[pxvid].vd; |
5761 | return vd; |
5838 | } |
5762 | } |
5839 | 5763 | ||
Line 5889... | Line 5813... | ||
5889 | unsigned long t, corr, state1, corr2, state2; |
5813 | unsigned long t, corr, state1, corr2, state2; |
5890 | u32 pxvid, ext_v; |
5814 | u32 pxvid, ext_v; |
Line 5891... | Line 5815... | ||
5891 | 5815 | ||
Line 5892... | Line 5816... | ||
5892 | assert_spin_locked(&mchdev_lock); |
5816 | assert_spin_locked(&mchdev_lock); |
5893 | 5817 | ||
5894 | pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->rps.cur_freq * 4)); |
5818 | pxvid = I915_READ(PXVFREQ(dev_priv->rps.cur_freq)); |
Line 5895... | Line 5819... | ||
5895 | pxvid = (pxvid >> 24) & 0x7f; |
5819 | pxvid = (pxvid >> 24) & 0x7f; |
Line 6132... | Line 6056... | ||
6132 | I915_WRITE(CSIEW0, 0x007f0000); |
6056 | I915_WRITE(CSIEW0, 0x007f0000); |
6133 | I915_WRITE(CSIEW1, 0x1e220004); |
6057 | I915_WRITE(CSIEW1, 0x1e220004); |
6134 | I915_WRITE(CSIEW2, 0x04000004); |
6058 | I915_WRITE(CSIEW2, 0x04000004); |
Line 6135... | Line 6059... | ||
6135 | 6059 | ||
6136 | for (i = 0; i < 5; i++) |
6060 | for (i = 0; i < 5; i++) |
6137 | I915_WRITE(PEW + (i * 4), 0); |
6061 | I915_WRITE(PEW(i), 0); |
6138 | for (i = 0; i < 3; i++) |
6062 | for (i = 0; i < 3; i++) |
Line 6139... | Line 6063... | ||
6139 | I915_WRITE(DEW + (i * 4), 0); |
6063 | I915_WRITE(DEW(i), 0); |
6140 | 6064 | ||
6141 | /* Program P-state weights to account for frequency power adjustment */ |
6065 | /* Program P-state weights to account for frequency power adjustment */ |
6142 | for (i = 0; i < 16; i++) { |
6066 | for (i = 0; i < 16; i++) { |
6143 | u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4)); |
6067 | u32 pxvidfreq = I915_READ(PXVFREQ(i)); |
6144 | unsigned long freq = intel_pxfreq(pxvidfreq); |
6068 | unsigned long freq = intel_pxfreq(pxvidfreq); |
6145 | unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >> |
6069 | unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >> |
Line 6159... | Line 6083... | ||
6159 | pxw[15] = 0; |
6083 | pxw[15] = 0; |
Line 6160... | Line 6084... | ||
6160 | 6084 | ||
6161 | for (i = 0; i < 4; i++) { |
6085 | for (i = 0; i < 4; i++) { |
6162 | u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) | |
6086 | u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) | |
6163 | (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]); |
6087 | (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]); |
6164 | I915_WRITE(PXW + (i * 4), val); |
6088 | I915_WRITE(PXW(i), val); |
Line 6165... | Line 6089... | ||
6165 | } |
6089 | } |
6166 | 6090 | ||
6167 | /* Adjust magic regs to magic values (more experimental results) */ |
6091 | /* Adjust magic regs to magic values (more experimental results) */ |
Line 6175... | Line 6099... | ||
6175 | I915_WRITE(EG5, 0x00140031); |
6099 | I915_WRITE(EG5, 0x00140031); |
6176 | I915_WRITE(EG6, 0); |
6100 | I915_WRITE(EG6, 0); |
6177 | I915_WRITE(EG7, 0); |
6101 | I915_WRITE(EG7, 0); |
Line 6178... | Line 6102... | ||
6178 | 6102 | ||
6179 | for (i = 0; i < 8; i++) |
6103 | for (i = 0; i < 8; i++) |
Line 6180... | Line 6104... | ||
6180 | I915_WRITE(PXWL + (i * 4), 0); |
6104 | I915_WRITE(PXWL(i), 0); |
6181 | 6105 | ||
Line 6182... | Line 6106... | ||
6182 | /* Enable PMON + select events */ |
6106 | /* Enable PMON + select events */ |
Line 6209... | Line 6133... | ||
6209 | { |
6133 | { |
6210 | struct drm_i915_private *dev_priv = dev->dev_private; |
6134 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 6211... | Line 6135... | ||
6211 | 6135 | ||
Line 6212... | Line -... | ||
6212 | // flush_delayed_work(&dev_priv->rps.delayed_resume_work); |
- | |
6213 | - | ||
6214 | /* |
- | |
6215 | * TODO: disable RPS interrupts on GEN9+ too once RPS support |
- | |
6216 | * is added for it. |
- | |
6217 | */ |
6136 | // flush_delayed_work(&dev_priv->rps.delayed_resume_work); |
6218 | if (INTEL_INFO(dev)->gen < 9) |
6137 | |
Line 6219... | Line 6138... | ||
6219 | gen6_disable_rps_interrupts(dev); |
6138 | gen6_disable_rps_interrupts(dev); |
6220 | } |
6139 | } |
Line 6244... | Line 6163... | ||
6244 | { |
6163 | { |
6245 | struct drm_i915_private *dev_priv = dev->dev_private; |
6164 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 6246... | Line 6165... | ||
6246 | 6165 | ||
6247 | if (IS_IRONLAKE_M(dev)) { |
6166 | if (IS_IRONLAKE_M(dev)) { |
6248 | ironlake_disable_drps(dev); |
- | |
6249 | ironlake_disable_rc6(dev); |
6167 | ironlake_disable_drps(dev); |
6250 | } else if (INTEL_INFO(dev)->gen >= 6) { |
6168 | } else if (INTEL_INFO(dev)->gen >= 6) { |
Line 6251... | Line 6169... | ||
6251 | intel_suspend_gt_powersave(dev); |
6169 | intel_suspend_gt_powersave(dev); |
6252 | 6170 | ||
Line 6272... | Line 6190... | ||
6272 | rps.delayed_resume_work.work); |
6190 | rps.delayed_resume_work.work); |
6273 | struct drm_device *dev = dev_priv->dev; |
6191 | struct drm_device *dev = dev_priv->dev; |
Line 6274... | Line 6192... | ||
6274 | 6192 | ||
Line 6275... | Line -... | ||
6275 | mutex_lock(&dev_priv->rps.hw_lock); |
- | |
6276 | - | ||
6277 | /* |
- | |
6278 | * TODO: reset/enable RPS interrupts on GEN9+ too, once RPS support is |
- | |
6279 | * added for it. |
- | |
6280 | */ |
6193 | mutex_lock(&dev_priv->rps.hw_lock); |
Line 6281... | Line 6194... | ||
6281 | if (INTEL_INFO(dev)->gen < 9) |
6194 | |
6282 | gen6_reset_rps_interrupts(dev); |
6195 | gen6_reset_rps_interrupts(dev); |
6283 | 6196 | ||
6284 | if (IS_CHERRYVIEW(dev)) { |
6197 | if (IS_CHERRYVIEW(dev)) { |
6285 | cherryview_enable_rps(dev); |
6198 | cherryview_enable_rps(dev); |
- | 6199 | } else if (IS_VALLEYVIEW(dev)) { |
|
6286 | } else if (IS_VALLEYVIEW(dev)) { |
6200 | valleyview_enable_rps(dev); |
- | 6201 | } else if (INTEL_INFO(dev)->gen >= 9) { |
|
- | 6202 | gen9_enable_rc6(dev); |
|
6287 | valleyview_enable_rps(dev); |
6203 | gen9_enable_rps(dev); |
6288 | } else if (INTEL_INFO(dev)->gen >= 9) { |
6204 | if (IS_SKYLAKE(dev)) |
6289 | gen9_enable_rps(dev); |
6205 | __gen6_update_ring_freq(dev); |
6290 | } else if (IS_BROADWELL(dev)) { |
6206 | } else if (IS_BROADWELL(dev)) { |
6291 | gen8_enable_rps(dev); |
6207 | gen8_enable_rps(dev); |
6292 | __gen6_update_ring_freq(dev); |
6208 | __gen6_update_ring_freq(dev); |
6293 | } else { |
6209 | } else { |
- | 6210 | gen6_enable_rps(dev); |
|
- | 6211 | __gen6_update_ring_freq(dev); |
|
- | 6212 | } |
|
- | 6213 | ||
- | 6214 | WARN_ON(dev_priv->rps.max_freq < dev_priv->rps.min_freq); |
|
- | 6215 | WARN_ON(dev_priv->rps.idle_freq > dev_priv->rps.max_freq); |
|
- | 6216 | ||
6294 | gen6_enable_rps(dev); |
6217 | WARN_ON(dev_priv->rps.efficient_freq < dev_priv->rps.min_freq); |
Line 6295... | Line -... | ||
6295 | __gen6_update_ring_freq(dev); |
- | |
6296 | } |
6218 | WARN_ON(dev_priv->rps.efficient_freq > dev_priv->rps.max_freq); |
Line 6297... | Line 6219... | ||
6297 | dev_priv->rps.enabled = true; |
6219 | |
Line 6298... | Line 6220... | ||
6298 | 6220 | dev_priv->rps.enabled = true; |
|
Line 6306... | Line 6228... | ||
6306 | 6228 | ||
6307 | void intel_enable_gt_powersave(struct drm_device *dev) |
6229 | void intel_enable_gt_powersave(struct drm_device *dev) |
6308 | { |
6230 | { |
Line -... | Line 6231... | ||
- | 6231 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 6232 | ||
- | 6233 | /* Powersaving is controlled by the host when inside a VM */ |
|
- | 6234 | if (intel_vgpu_active(dev)) |
|
6309 | struct drm_i915_private *dev_priv = dev->dev_private; |
6235 | return; |
6310 | 6236 | ||
6311 | if (IS_IRONLAKE_M(dev)) { |
6237 | if (IS_IRONLAKE_M(dev)) { |
6312 | mutex_lock(&dev->struct_mutex); |
- | |
6313 | ironlake_enable_drps(dev); |
6238 | mutex_lock(&dev->struct_mutex); |
6314 | ironlake_enable_rc6(dev); |
6239 | ironlake_enable_drps(dev); |
6315 | intel_init_emon(dev); |
6240 | intel_init_emon(dev); |
6316 | mutex_unlock(&dev->struct_mutex); |
6241 | mutex_unlock(&dev->struct_mutex); |
6317 | } else if (INTEL_INFO(dev)->gen >= 6) { |
6242 | } else if (INTEL_INFO(dev)->gen >= 6) { |
Line 6357... | Line 6282... | ||
6357 | } |
6282 | } |
Line 6358... | Line 6283... | ||
6358 | 6283 | ||
6359 | static void g4x_disable_trickle_feed(struct drm_device *dev) |
6284 | static void g4x_disable_trickle_feed(struct drm_device *dev) |
6360 | { |
6285 | { |
6361 | struct drm_i915_private *dev_priv = dev->dev_private; |
6286 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 6362... | Line 6287... | ||
6362 | int pipe; |
6287 | enum pipe pipe; |
6363 | 6288 | ||
6364 | for_each_pipe(dev_priv, pipe) { |
6289 | for_each_pipe(dev_priv, pipe) { |
6365 | I915_WRITE(DSPCNTR(pipe), |
6290 | I915_WRITE(DSPCNTR(pipe), |
- | 6291 | I915_READ(DSPCNTR(pipe)) | |
|
6366 | I915_READ(DSPCNTR(pipe)) | |
6292 | DISPPLANE_TRICKLE_FEED_DISABLE); |
- | 6293 | ||
6367 | DISPPLANE_TRICKLE_FEED_DISABLE); |
6294 | I915_WRITE(DSPSURF(pipe), I915_READ(DSPSURF(pipe))); |
6368 | intel_flush_primary_plane(dev_priv, pipe); |
6295 | POSTING_READ(DSPSURF(pipe)); |
Line 6369... | Line 6296... | ||
6369 | } |
6296 | } |
6370 | } |
6297 | } |
Line 6626... | Line 6553... | ||
6626 | 6553 | ||
6627 | /* |
6554 | /* |
6628 | * TODO: this bit should only be enabled when really needed, then |
6555 | * TODO: this bit should only be enabled when really needed, then |
6629 | * disabled when not needed anymore in order to save power. |
6556 | * disabled when not needed anymore in order to save power. |
6630 | */ |
6557 | */ |
6631 | if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) |
6558 | if (HAS_PCH_LPT_LP(dev)) |
6632 | I915_WRITE(SOUTH_DSPCLK_GATE_D, |
6559 | I915_WRITE(SOUTH_DSPCLK_GATE_D, |
6633 | I915_READ(SOUTH_DSPCLK_GATE_D) | |
6560 | I915_READ(SOUTH_DSPCLK_GATE_D) | |
Line 6634... | Line 6561... | ||
6634 | PCH_LP_PARTITION_LEVEL_DISABLE); |
6561 | PCH_LP_PARTITION_LEVEL_DISABLE); |
6635 | 6562 | ||
6636 | /* WADPOClockGatingDisable:hsw */ |
6563 | /* WADPOClockGatingDisable:hsw */ |
6637 | I915_WRITE(_TRANSA_CHICKEN1, |
6564 | I915_WRITE(TRANS_CHICKEN1(PIPE_A), |
6638 | I915_READ(_TRANSA_CHICKEN1) | |
6565 | I915_READ(TRANS_CHICKEN1(PIPE_A)) | |
Line 6639... | Line 6566... | ||
6639 | TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); |
6566 | TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); |
6640 | } |
6567 | } |
6641 | 6568 | ||
Line 6642... | Line 6569... | ||
6642 | static void lpt_suspend_hw(struct drm_device *dev) |
6569 | static void lpt_suspend_hw(struct drm_device *dev) |
6643 | { |
6570 | { |
Line 6644... | Line 6571... | ||
6644 | struct drm_i915_private *dev_priv = dev->dev_private; |
6571 | struct drm_i915_private *dev_priv = dev->dev_private; |
6645 | 6572 | ||
6646 | if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { |
6573 | if (HAS_PCH_LPT_LP(dev)) { |
Line 6653... | Line 6580... | ||
6653 | 6580 | ||
6654 | static void broadwell_init_clock_gating(struct drm_device *dev) |
6581 | static void broadwell_init_clock_gating(struct drm_device *dev) |
6655 | { |
6582 | { |
6656 | struct drm_i915_private *dev_priv = dev->dev_private; |
6583 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | 6584 | enum pipe pipe; |
|
Line 6657... | Line -... | ||
6657 | enum pipe pipe; |
- | |
6658 | - | ||
6659 | I915_WRITE(WM3_LP_ILK, 0); |
6585 | uint32_t misccpctl; |
Line 6660... | Line 6586... | ||
6660 | I915_WRITE(WM2_LP_ILK, 0); |
6586 | |
6661 | I915_WRITE(WM1_LP_ILK, 0); |
6587 | ilk_init_lp_watermarks(dev); |
Line 6662... | Line 6588... | ||
6662 | 6588 | ||
Line 6685... | Line 6611... | ||
6685 | 6611 | ||
6686 | /* WaDisableSDEUnitClockGating:bdw */ |
6612 | /* WaDisableSDEUnitClockGating:bdw */ |
6687 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
6613 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
Line -... | Line 6614... | ||
- | 6614 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); |
|
- | 6615 | ||
- | 6616 | /* |
|
- | 6617 | * WaProgramL3SqcReg1Default:bdw |
|
- | 6618 | * WaTempDisableDOPClkGating:bdw |
|
- | 6619 | */ |
|
- | 6620 | misccpctl = I915_READ(GEN7_MISCCPCTL); |
|
- | 6621 | I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); |
|
- | 6622 | I915_WRITE(GEN8_L3SQCREG1, BDW_WA_L3SQCREG1_DEFAULT); |
|
- | 6623 | I915_WRITE(GEN7_MISCCPCTL, misccpctl); |
|
- | 6624 | ||
- | 6625 | /* |
|
- | 6626 | * WaGttCachingOffByDefault:bdw |
|
- | 6627 | * GTT cache may not work with big pages, so if those |
|
- | 6628 | * are ever enabled GTT cache may need to be disabled. |
|
- | 6629 | */ |
|
6688 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); |
6630 | I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL); |
6689 | 6631 | ||
Line 6690... | Line 6632... | ||
6690 | lpt_init_clock_gating(dev); |
6632 | lpt_init_clock_gating(dev); |
6691 | } |
6633 | } |
Line 6730... | Line 6672... | ||
6730 | * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). |
6672 | * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). |
6731 | */ |
6673 | */ |
6732 | I915_WRITE(GEN7_GT_MODE, |
6674 | I915_WRITE(GEN7_GT_MODE, |
6733 | _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); |
6675 | _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); |
Line -... | Line 6676... | ||
- | 6676 | ||
- | 6677 | /* WaSampleCChickenBitEnable:hsw */ |
|
- | 6678 | I915_WRITE(HALF_SLICE_CHICKEN3, |
|
- | 6679 | _MASKED_BIT_ENABLE(HSW_SAMPLE_C_PERFORMANCE)); |
|
6734 | 6680 | ||
6735 | /* WaSwitchSolVfFArbitrationPriority:hsw */ |
6681 | /* WaSwitchSolVfFArbitrationPriority:hsw */ |
Line 6736... | Line 6682... | ||
6736 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); |
6682 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); |
6737 | 6683 | ||
Line 6838... | Line 6784... | ||
6838 | cpt_init_clock_gating(dev); |
6784 | cpt_init_clock_gating(dev); |
Line 6839... | Line 6785... | ||
6839 | 6785 | ||
6840 | gen6_check_mch_setup(dev); |
6786 | gen6_check_mch_setup(dev); |
Line -... | Line 6787... | ||
- | 6787 | } |
|
- | 6788 | ||
- | 6789 | static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv) |
|
- | 6790 | { |
|
- | 6791 | I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); |
|
- | 6792 | ||
- | 6793 | /* |
|
- | 6794 | * Disable trickle feed and enable pnd deadline calculation |
|
- | 6795 | */ |
|
- | 6796 | I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE); |
|
- | 6797 | I915_WRITE(CBR1_VLV, 0); |
|
6841 | } |
6798 | } |
6842 | 6799 | ||
6843 | static void valleyview_init_clock_gating(struct drm_device *dev) |
6800 | static void valleyview_init_clock_gating(struct drm_device *dev) |
Line 6844... | Line 6801... | ||
6844 | { |
6801 | { |
Line 6845... | Line 6802... | ||
6845 | struct drm_i915_private *dev_priv = dev->dev_private; |
6802 | struct drm_i915_private *dev_priv = dev->dev_private; |
6846 | 6803 | ||
6847 | I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); |
6804 | vlv_init_display_clock_gating(dev_priv); |
Line 6890... | Line 6847... | ||
6890 | * Disabling L3 clock gating- MMIO 940c[25] = 1 |
6847 | * Disabling L3 clock gating- MMIO 940c[25] = 1 |
6891 | * Set bit 25, to disable L3_BANK_2x_CLK_GATING */ |
6848 | * Set bit 25, to disable L3_BANK_2x_CLK_GATING */ |
6892 | I915_WRITE(GEN7_UCGCTL4, |
6849 | I915_WRITE(GEN7_UCGCTL4, |
6893 | I915_READ(GEN7_UCGCTL4) | GEN7_L3BANK2X_CLOCK_GATE_DISABLE); |
6850 | I915_READ(GEN7_UCGCTL4) | GEN7_L3BANK2X_CLOCK_GATE_DISABLE); |
Line 6894... | Line -... | ||
6894 | - | ||
6895 | I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE); |
- | |
6896 | 6851 | ||
6897 | /* |
6852 | /* |
6898 | * BSpec says this must be set, even though |
6853 | * BSpec says this must be set, even though |
6899 | * WaDisable4x2SubspanOptimization isn't listed for VLV. |
6854 | * WaDisable4x2SubspanOptimization isn't listed for VLV. |
6900 | */ |
6855 | */ |
6901 | I915_WRITE(CACHE_MODE_1, |
6856 | I915_WRITE(CACHE_MODE_1, |
Line 6902... | Line 6857... | ||
6902 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); |
6857 | _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); |
- | 6858 | ||
- | 6859 | /* |
|
- | 6860 | * BSpec recommends 8x4 when MSAA is used, |
|
- | 6861 | * however in practice 16x4 seems fastest. |
|
- | 6862 | * |
|
- | 6863 | * Note that PS/WM thread counts depend on the WIZ hashing |
|
- | 6864 | * disable bit, which we don't touch here, but it's good |
|
- | 6865 | * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). |
|
- | 6866 | */ |
|
- | 6867 | I915_WRITE(GEN7_GT_MODE, |
|
- | 6868 | _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); |
|
6903 | 6869 | ||
6904 | /* |
6870 | /* |
6905 | * WaIncreaseL3CreditsForVLVB0:vlv |
6871 | * WaIncreaseL3CreditsForVLVB0:vlv |
6906 | * This is the hardware default actually. |
6872 | * This is the hardware default actually. |
Line 6917... | Line 6883... | ||
6917 | 6883 | ||
6918 | static void cherryview_init_clock_gating(struct drm_device *dev) |
6884 | static void cherryview_init_clock_gating(struct drm_device *dev) |
6919 | { |
6885 | { |
Line 6920... | Line 6886... | ||
6920 | struct drm_i915_private *dev_priv = dev->dev_private; |
6886 | struct drm_i915_private *dev_priv = dev->dev_private; |
6921 | - | ||
6922 | I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); |
- | |
Line 6923... | Line 6887... | ||
6923 | 6887 | ||
6924 | I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE); |
6888 | vlv_init_display_clock_gating(dev_priv); |
6925 | 6889 | ||
6926 | /* WaVSRefCountFullforceMissDisable:chv */ |
6890 | /* WaVSRefCountFullforceMissDisable:chv */ |
Line 6938... | Line 6902... | ||
6938 | GEN6_CSUNIT_CLOCK_GATE_DISABLE); |
6902 | GEN6_CSUNIT_CLOCK_GATE_DISABLE); |
Line 6939... | Line 6903... | ||
6939 | 6903 | ||
6940 | /* WaDisableSDEUnitClockGating:chv */ |
6904 | /* WaDisableSDEUnitClockGating:chv */ |
6941 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
6905 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
- | 6906 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); |
|
- | 6907 | ||
- | 6908 | /* |
|
- | 6909 | * GTT cache may not work with big pages, so if those |
|
- | 6910 | * are ever enabled GTT cache may need to be disabled. |
|
- | 6911 | */ |
|
6942 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); |
6912 | I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL); |
Line 6943... | Line 6913... | ||
6943 | } |
6913 | } |
6944 | 6914 | ||
6945 | static void g4x_init_clock_gating(struct drm_device *dev) |
6915 | static void g4x_init_clock_gating(struct drm_device *dev) |
Line 7054... | Line 7024... | ||
7054 | 7024 | ||
7055 | void intel_init_clock_gating(struct drm_device *dev) |
7025 | void intel_init_clock_gating(struct drm_device *dev) |
7056 | { |
7026 | { |
Line -... | Line 7027... | ||
- | 7027 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
7057 | struct drm_i915_private *dev_priv = dev->dev_private; |
7028 | |
7058 | 7029 | if (dev_priv->display.init_clock_gating) |
|
Line 7059... | Line 7030... | ||
7059 | dev_priv->display.init_clock_gating(dev); |
7030 | dev_priv->display.init_clock_gating(dev); |
7060 | } |
7031 | } |
7061 | 7032 | ||
7062 | void intel_suspend_hw(struct drm_device *dev) |
7033 | void intel_suspend_hw(struct drm_device *dev) |
7063 | { |
7034 | { |
Line 7064... | Line -... | ||
7064 | if (HAS_PCH_LPT(dev)) |
- | |
7065 | lpt_suspend_hw(dev); |
- | |
7066 | } |
- | |
7067 | - | ||
7068 | static void intel_init_fbc(struct drm_i915_private *dev_priv) |
- | |
7069 | { |
- | |
7070 | if (!HAS_FBC(dev_priv)) { |
- | |
7071 | dev_priv->fbc.enabled = false; |
- | |
7072 | return; |
- | |
7073 | } |
- | |
7074 | - | ||
7075 | if (INTEL_INFO(dev_priv)->gen >= 7) { |
- | |
7076 | dev_priv->display.fbc_enabled = ironlake_fbc_enabled; |
- | |
7077 | dev_priv->display.enable_fbc = gen7_enable_fbc; |
- | |
7078 | dev_priv->display.disable_fbc = ironlake_disable_fbc; |
- | |
7079 | } else if (INTEL_INFO(dev_priv)->gen >= 5) { |
- | |
7080 | dev_priv->display.fbc_enabled = ironlake_fbc_enabled; |
- | |
7081 | dev_priv->display.enable_fbc = ironlake_enable_fbc; |
- | |
7082 | dev_priv->display.disable_fbc = ironlake_disable_fbc; |
- | |
7083 | } else if (IS_GM45(dev_priv)) { |
- | |
7084 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; |
- | |
7085 | dev_priv->display.enable_fbc = g4x_enable_fbc; |
- | |
7086 | dev_priv->display.disable_fbc = g4x_disable_fbc; |
- | |
7087 | } else { |
- | |
7088 | dev_priv->display.fbc_enabled = i8xx_fbc_enabled; |
- | |
7089 | dev_priv->display.enable_fbc = i8xx_enable_fbc; |
- | |
7090 | dev_priv->display.disable_fbc = i8xx_disable_fbc; |
- | |
7091 | - | ||
7092 | /* This value was pulled out of someone's hat */ |
- | |
7093 | I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT); |
- | |
7094 | } |
- | |
7095 | 7035 | if (HAS_PCH_LPT(dev)) |
|
7096 | dev_priv->fbc.enabled = dev_priv->display.fbc_enabled(dev_priv->dev); |
7036 | lpt_suspend_hw(dev); |
7097 | } |
7037 | } |
7098 | 7038 | ||
Line 7099... | Line 7039... | ||
7099 | /* Set up chip specific power management-related functions */ |
7039 | /* Set up chip specific power management-related functions */ |
Line 7100... | Line 7040... | ||
7100 | void intel_init_pm(struct drm_device *dev) |
7040 | void intel_init_pm(struct drm_device *dev) |
7101 | { |
7041 | { |
7102 | struct drm_i915_private *dev_priv = dev->dev_private; |
7042 | struct drm_i915_private *dev_priv = dev->dev_private; |
7103 | 7043 | ||
Line 7111... | Line 7051... | ||
7111 | 7051 | ||
7112 | /* For FIFO watermark updates */ |
7052 | /* For FIFO watermark updates */ |
7113 | if (INTEL_INFO(dev)->gen >= 9) { |
7053 | if (INTEL_INFO(dev)->gen >= 9) { |
Line -... | Line 7054... | ||
- | 7054 | skl_setup_wm_latency(dev); |
|
7114 | skl_setup_wm_latency(dev); |
7055 | |
- | 7056 | if (IS_BROXTON(dev)) |
|
7115 | 7057 | dev_priv->display.init_clock_gating = |
|
7116 | dev_priv->display.init_clock_gating = gen9_init_clock_gating; |
7058 | bxt_init_clock_gating; |
7117 | dev_priv->display.update_wm = skl_update_wm; |
7059 | dev_priv->display.update_wm = skl_update_wm; |
7118 | dev_priv->display.update_sprite_wm = skl_update_sprite_wm; |
7060 | dev_priv->display.update_sprite_wm = skl_update_sprite_wm; |
Line 7139... | Line 7081... | ||
7139 | else if (IS_HASWELL(dev)) |
7081 | else if (IS_HASWELL(dev)) |
7140 | dev_priv->display.init_clock_gating = haswell_init_clock_gating; |
7082 | dev_priv->display.init_clock_gating = haswell_init_clock_gating; |
7141 | else if (INTEL_INFO(dev)->gen == 8) |
7083 | else if (INTEL_INFO(dev)->gen == 8) |
7142 | dev_priv->display.init_clock_gating = broadwell_init_clock_gating; |
7084 | dev_priv->display.init_clock_gating = broadwell_init_clock_gating; |
7143 | } else if (IS_CHERRYVIEW(dev)) { |
7085 | } else if (IS_CHERRYVIEW(dev)) { |
7144 | dev_priv->display.update_wm = cherryview_update_wm; |
7086 | vlv_setup_wm_latency(dev); |
- | 7087 | ||
7145 | dev_priv->display.update_sprite_wm = valleyview_update_sprite_wm; |
7088 | dev_priv->display.update_wm = vlv_update_wm; |
7146 | dev_priv->display.init_clock_gating = |
7089 | dev_priv->display.init_clock_gating = |
7147 | cherryview_init_clock_gating; |
7090 | cherryview_init_clock_gating; |
7148 | } else if (IS_VALLEYVIEW(dev)) { |
7091 | } else if (IS_VALLEYVIEW(dev)) { |
7149 | dev_priv->display.update_wm = valleyview_update_wm; |
7092 | vlv_setup_wm_latency(dev); |
- | 7093 | ||
7150 | dev_priv->display.update_sprite_wm = valleyview_update_sprite_wm; |
7094 | dev_priv->display.update_wm = vlv_update_wm; |
7151 | dev_priv->display.init_clock_gating = |
7095 | dev_priv->display.init_clock_gating = |
7152 | valleyview_init_clock_gating; |
7096 | valleyview_init_clock_gating; |
7153 | } else if (IS_PINEVIEW(dev)) { |
7097 | } else if (IS_PINEVIEW(dev)) { |
7154 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), |
7098 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), |
7155 | dev_priv->is_ddr3, |
7099 | dev_priv->is_ddr3, |
Line 7262... | Line 7206... | ||
7262 | } |
7206 | } |
7263 | } |
7207 | } |
Line 7264... | Line 7208... | ||
7264 | 7208 | ||
7265 | static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) |
7209 | static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) |
7266 | { |
7210 | { |
Line 7267... | Line 7211... | ||
7267 | int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4); |
7211 | int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000); |
7268 | 7212 | ||
7269 | div = vlv_gpu_freq_div(czclk_freq); |
7213 | div = vlv_gpu_freq_div(czclk_freq); |
Line 7270... | Line 7214... | ||
7270 | if (div < 0) |
7214 | if (div < 0) |
7271 | return div; |
7215 | return div; |
Line 7272... | Line 7216... | ||
7272 | 7216 | ||
7273 | return DIV_ROUND_CLOSEST(czclk_freq * (val + 6 - 0xbd), div); |
7217 | return DIV_ROUND_CLOSEST(czclk_freq * (val + 6 - 0xbd), div); |
7274 | } |
7218 | } |
Line 7275... | Line 7219... | ||
7275 | 7219 | ||
7276 | static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) |
7220 | static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) |
7277 | { |
7221 | { |
Line 7278... | Line 7222... | ||
7278 | int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4); |
7222 | int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000); |
7279 | 7223 | ||
Line 7280... | Line 7224... | ||
7280 | mul = vlv_gpu_freq_div(czclk_freq); |
7224 | mul = vlv_gpu_freq_div(czclk_freq); |
7281 | if (mul < 0) |
7225 | if (mul < 0) |
7282 | return mul; |
7226 | return mul; |
Line 7283... | Line 7227... | ||
7283 | 7227 | ||
7284 | return DIV_ROUND_CLOSEST(mul * val, czclk_freq) + 0xbd - 6; |
7228 | return DIV_ROUND_CLOSEST(mul * val, czclk_freq) + 0xbd - 6; |
7285 | } |
7229 | } |
Line 7286... | Line 7230... | ||
7286 | 7230 | ||
7287 | static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) |
7231 | static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) |
Line 7288... | Line 7232... | ||
7288 | { |
7232 | { |
7289 | int div, czclk_freq = dev_priv->rps.cz_freq; |
7233 | int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000); |
7290 | 7234 | ||
Line 7291... | Line 7235... | ||
7291 | div = vlv_gpu_freq_div(czclk_freq) / 2; |
7235 | div = vlv_gpu_freq_div(czclk_freq) / 2; |
7292 | if (div < 0) |
7236 | if (div < 0) |
7293 | return div; |
7237 | return div; |
Line 7294... | Line 7238... | ||
7294 | 7238 | ||
7295 | return DIV_ROUND_CLOSEST(czclk_freq * val, 2 * div) / 2; |
7239 | return DIV_ROUND_CLOSEST(czclk_freq * val, 2 * div) / 2; |
7296 | } |
7240 | } |
Line 7297... | Line 7241... | ||
7297 | 7241 | ||
7298 | static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) |
7242 | static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) |
- | 7243 | { |
|
- | 7244 | int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000); |
|
7299 | { |
7245 | |
- | 7246 | mul = vlv_gpu_freq_div(czclk_freq) / 2; |
|
- | 7247 | if (mul < 0) |
|
- | 7248 | return mul; |
|
- | 7249 | ||
- | 7250 | /* CHV needs even values */ |
|
- | 7251 | return DIV_ROUND_CLOSEST(val * 2 * mul, czclk_freq) * 2; |
|
- | 7252 | } |
|
Line -... | Line 7253... | ||
- | 7253 | ||
- | 7254 | int intel_gpu_freq(struct drm_i915_private *dev_priv, int val) |
|
- | 7255 | { |
|
- | 7256 | if (IS_GEN9(dev_priv->dev)) |
|
- | 7257 | return DIV_ROUND_CLOSEST(val * GT_FREQUENCY_MULTIPLIER, |
|
7300 | int mul, czclk_freq = dev_priv->rps.cz_freq; |
7258 | GEN9_FREQ_SCALER); |
7301 | 7259 | else if (IS_CHERRYVIEW(dev_priv->dev)) |
|
7302 | mul = vlv_gpu_freq_div(czclk_freq) / 2; |
7260 | return chv_gpu_freq(dev_priv, val); |
7303 | if (mul < 0) |
7261 | else if (IS_VALLEYVIEW(dev_priv->dev)) |
- | 7262 | return byt_gpu_freq(dev_priv, val); |
|
- | 7263 | else |
|
- | 7264 | return val * GT_FREQUENCY_MULTIPLIER; |
|
Line -... | Line 7265... | ||
- | 7265 | } |
|
- | 7266 | ||
- | 7267 | int intel_freq_opcode(struct drm_i915_private *dev_priv, int val) |
|
- | 7268 | { |
|
- | 7269 | if (IS_GEN9(dev_priv->dev)) |
|
- | 7270 | return DIV_ROUND_CLOSEST(val * GEN9_FREQ_SCALER, |
|
- | 7271 | GT_FREQUENCY_MULTIPLIER); |
|
- | 7272 | else if (IS_CHERRYVIEW(dev_priv->dev)) |
|
- | 7273 | return chv_freq_opcode(dev_priv, val); |
|
- | 7274 | else if (IS_VALLEYVIEW(dev_priv->dev)) |
|
- | 7275 | return byt_freq_opcode(dev_priv, val); |
|
- | 7276 | else |
|
- | 7277 | return DIV_ROUND_CLOSEST(val, GT_FREQUENCY_MULTIPLIER); |
|
- | 7278 | } |
|
- | 7279 | ||
7304 | return mul; |
7280 | struct request_boost { |
7305 | 7281 | struct work_struct work; |
|
Line -... | Line 7282... | ||
- | 7282 | struct drm_i915_gem_request *req; |
|
7306 | /* CHV needs even values */ |
7283 | }; |
7307 | return DIV_ROUND_CLOSEST(val * 2 * mul, czclk_freq) * 2; |
7284 | |
7308 | } |
7285 | static void __intel_rps_boost_work(struct work_struct *work) |
Line 7309... | Line -... | ||
7309 | - | ||
7310 | int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val) |
7286 | { |
7311 | { |
- | |
7312 | int ret = -1; |
7287 | struct request_boost *boost = container_of(work, struct request_boost, work); |
Line -... | Line 7288... | ||
- | 7288 | struct drm_i915_gem_request *req = boost->req; |
|
7313 | 7289 | ||
- | 7290 | if (!i915_gem_request_completed(req, true)) |
|
- | 7291 | gen6_rps_boost(to_i915(req->ring->dev), NULL, |
|
- | 7292 | req->emitted_jiffies); |
|
- | 7293 | ||
- | 7294 | i915_gem_request_unreference__unlocked(req); |
|
- | 7295 | kfree(boost); |
|
- | 7296 | } |
|
- | 7297 | ||
- | 7298 | void intel_queue_rps_boost_for_request(struct drm_device *dev, |
|
- | 7299 | struct drm_i915_gem_request *req) |
|
7314 | if (IS_CHERRYVIEW(dev_priv->dev)) |
7300 | { |
Line 7315... | Line 7301... | ||
7315 | ret = chv_gpu_freq(dev_priv, val); |
7301 | struct request_boost *boost; |
7316 | else if (IS_VALLEYVIEW(dev_priv->dev)) |
7302 | |
7317 | ret = byt_gpu_freq(dev_priv, val); |
7303 | if (req == NULL || INTEL_INFO(dev)->gen < 6) |
Line 7318... | Line 7304... | ||
7318 | 7304 | return; |
|
- | 7305 | ||
Line 7319... | Line 7306... | ||
7319 | return ret; |
7306 | if (i915_gem_request_completed(req, true)) |
7320 | } |
7307 | return; |
- | 7308 | ||
- | 7309 | boost = kmalloc(sizeof(*boost), GFP_ATOMIC); |
|
- | 7310 | if (boost == NULL) |
|
Line 7321... | Line 7311... | ||
7321 | 7311 | return; |
|
7322 | int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val) |
7312 |