.. | .. |
---|
25 | 25 | * |
---|
26 | 26 | */ |
---|
27 | 27 | |
---|
28 | | -#include <linux/cpufreq.h> |
---|
29 | | -#include <drm/drm_plane_helper.h> |
---|
30 | | -#include "i915_drv.h" |
---|
31 | | -#include "intel_drv.h" |
---|
32 | | -#include "../../../platform/x86/intel_ips.h" |
---|
33 | 28 | #include <linux/module.h> |
---|
34 | | -#include <drm/drm_atomic_helper.h> |
---|
| 29 | +#include <linux/pm_runtime.h> |
---|
35 | 30 | |
---|
36 | | -/** |
---|
37 | | - * DOC: RC6 |
---|
38 | | - * |
---|
39 | | - * RC6 is a special power stage which allows the GPU to enter an very |
---|
40 | | - * low-voltage mode when idle, using down to 0V while at this stage. This |
---|
41 | | - * stage is entered automatically when the GPU is idle when RC6 support is |
---|
42 | | - * enabled, and as soon as new workload arises GPU wakes up automatically as well. |
---|
43 | | - * |
---|
44 | | - * There are different RC6 modes available in Intel GPU, which differentiate |
---|
45 | | - * among each other with the latency required to enter and leave RC6 and |
---|
46 | | - * voltage consumed by the GPU in different states. |
---|
47 | | - * |
---|
48 | | - * The combination of the following flags define which states GPU is allowed |
---|
49 | | - * to enter, while RC6 is the normal RC6 state, RC6p is the deep RC6, and |
---|
50 | | - * RC6pp is deepest RC6. Their support by hardware varies according to the |
---|
51 | | - * GPU, BIOS, chipset and platform. RC6 is usually the safest one and the one |
---|
52 | | - * which brings the most power savings; deeper states save more power, but |
---|
53 | | - * require higher latency to switch to and wake up. |
---|
54 | | - */ |
---|
| 31 | +#include <drm/drm_atomic_helper.h> |
---|
| 32 | +#include <drm/drm_fourcc.h> |
---|
| 33 | +#include <drm/drm_plane_helper.h> |
---|
| 34 | + |
---|
| 35 | +#include "display/intel_atomic.h" |
---|
| 36 | +#include "display/intel_bw.h" |
---|
| 37 | +#include "display/intel_display_types.h" |
---|
| 38 | +#include "display/intel_fbc.h" |
---|
| 39 | +#include "display/intel_sprite.h" |
---|
| 40 | + |
---|
| 41 | +#include "gt/intel_llc.h" |
---|
| 42 | + |
---|
| 43 | +#include "i915_drv.h" |
---|
| 44 | +#include "i915_fixed.h" |
---|
| 45 | +#include "i915_irq.h" |
---|
| 46 | +#include "i915_trace.h" |
---|
| 47 | +#include "intel_pm.h" |
---|
| 48 | +#include "intel_sideband.h" |
---|
| 49 | +#include "../../../platform/x86/intel_ips.h" |
---|
| 50 | + |
---|
| 51 | +/* Stores plane specific WM parameters */ |
---|
| 52 | +struct skl_wm_params { |
---|
| 53 | + bool x_tiled, y_tiled; |
---|
| 54 | + bool rc_surface; |
---|
| 55 | + bool is_planar; |
---|
| 56 | + u32 width; |
---|
| 57 | + u8 cpp; |
---|
| 58 | + u32 plane_pixel_rate; |
---|
| 59 | + u32 y_min_scanlines; |
---|
| 60 | + u32 plane_bytes_per_line; |
---|
| 61 | + uint_fixed_16_16_t plane_blocks_per_line; |
---|
| 62 | + uint_fixed_16_16_t y_tile_minimum; |
---|
| 63 | + u32 linetime_us; |
---|
| 64 | + u32 dbuf_block_size; |
---|
| 65 | +}; |
---|
| 66 | + |
---|
| 67 | +/* used in computing the new watermarks state */ |
---|
| 68 | +struct intel_wm_config { |
---|
| 69 | + unsigned int num_pipes_active; |
---|
| 70 | + bool sprites_enabled; |
---|
| 71 | + bool sprites_scaled; |
---|
| 72 | +}; |
---|
55 | 73 | |
---|
56 | 74 | static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
57 | 75 | { |
---|
.. | .. |
---|
76 | 94 | I915_WRITE(GEN8_CHICKEN_DCPR_1, |
---|
77 | 95 | I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM); |
---|
78 | 96 | |
---|
79 | | - /* WaFbcTurnOffFbcWatermark:skl,bxt,kbl,cfl */ |
---|
80 | | - /* WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl */ |
---|
| 97 | + /* |
---|
| 98 | + * WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl |
---|
| 99 | + * Display WA #0859: skl,bxt,kbl,glk,cfl |
---|
| 100 | + */ |
---|
81 | 101 | I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | |
---|
82 | | - DISP_FBC_WM_DIS | |
---|
83 | 102 | DISP_FBC_MEMORY_WAKE); |
---|
84 | | - |
---|
85 | | - /* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl,cfl */ |
---|
86 | | - I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | |
---|
87 | | - ILK_DPFC_DISABLE_DUMMY0); |
---|
88 | | - |
---|
89 | | - if (IS_SKYLAKE(dev_priv)) { |
---|
90 | | - /* WaDisableDopClockGating */ |
---|
91 | | - I915_WRITE(GEN7_MISCCPCTL, I915_READ(GEN7_MISCCPCTL) |
---|
92 | | - & ~GEN7_DOP_CLOCK_GATE_ENABLE); |
---|
93 | | - } |
---|
94 | 103 | } |
---|
95 | 104 | |
---|
96 | 105 | static void bxt_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
.. | .. |
---|
122 | 131 | * application, using batch buffers or any other means. |
---|
123 | 132 | */ |
---|
124 | 133 | I915_WRITE(RM_TIMEOUT, MMIO_TIMEOUT_US(950)); |
---|
| 134 | + |
---|
| 135 | + /* |
---|
| 136 | + * WaFbcTurnOffFbcWatermark:bxt |
---|
| 137 | + * Display WA #0562: bxt |
---|
| 138 | + */ |
---|
| 139 | + I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | |
---|
| 140 | + DISP_FBC_WM_DIS); |
---|
| 141 | + |
---|
| 142 | + /* |
---|
| 143 | + * WaFbcHighMemBwCorruptionAvoidance:bxt |
---|
| 144 | + * Display WA #0883: bxt |
---|
| 145 | + */ |
---|
| 146 | + I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | |
---|
| 147 | + ILK_DPFC_DISABLE_DUMMY0); |
---|
125 | 148 | } |
---|
126 | 149 | |
---|
127 | 150 | static void glk_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
.. | .. |
---|
135 | 158 | */ |
---|
136 | 159 | I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) | |
---|
137 | 160 | PWM1_GATING_DIS | PWM2_GATING_DIS); |
---|
138 | | - |
---|
139 | | - /* WaDDIIOTimeout:glk */ |
---|
140 | | - if (IS_GLK_REVID(dev_priv, 0, GLK_REVID_A1)) { |
---|
141 | | - u32 val = I915_READ(CHICKEN_MISC_2); |
---|
142 | | - val &= ~(GLK_CL0_PWR_DOWN | |
---|
143 | | - GLK_CL1_PWR_DOWN | |
---|
144 | | - GLK_CL2_PWR_DOWN); |
---|
145 | | - I915_WRITE(CHICKEN_MISC_2, val); |
---|
146 | | - } |
---|
147 | | - |
---|
148 | 161 | } |
---|
149 | 162 | |
---|
150 | | -static void i915_pineview_get_mem_freq(struct drm_i915_private *dev_priv) |
---|
| 163 | +static void pnv_get_mem_freq(struct drm_i915_private *dev_priv) |
---|
151 | 164 | { |
---|
152 | 165 | u32 tmp; |
---|
153 | 166 | |
---|
.. | .. |
---|
185 | 198 | dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0; |
---|
186 | 199 | } |
---|
187 | 200 | |
---|
188 | | -static void i915_ironlake_get_mem_freq(struct drm_i915_private *dev_priv) |
---|
| 201 | +static void ilk_get_mem_freq(struct drm_i915_private *dev_priv) |
---|
189 | 202 | { |
---|
190 | 203 | u16 ddrpll, csipll; |
---|
191 | 204 | |
---|
192 | | - ddrpll = I915_READ16(DDRMPLL1); |
---|
193 | | - csipll = I915_READ16(CSIPLL0); |
---|
| 205 | + ddrpll = intel_uncore_read16(&dev_priv->uncore, DDRMPLL1); |
---|
| 206 | + csipll = intel_uncore_read16(&dev_priv->uncore, CSIPLL0); |
---|
194 | 207 | |
---|
195 | 208 | switch (ddrpll & 0xff) { |
---|
196 | 209 | case 0xc: |
---|
.. | .. |
---|
206 | 219 | dev_priv->mem_freq = 1600; |
---|
207 | 220 | break; |
---|
208 | 221 | default: |
---|
209 | | - DRM_DEBUG_DRIVER("unknown memory frequency 0x%02x\n", |
---|
210 | | - ddrpll & 0xff); |
---|
| 222 | + drm_dbg(&dev_priv->drm, "unknown memory frequency 0x%02x\n", |
---|
| 223 | + ddrpll & 0xff); |
---|
211 | 224 | dev_priv->mem_freq = 0; |
---|
212 | 225 | break; |
---|
213 | 226 | } |
---|
214 | | - |
---|
215 | | - dev_priv->ips.r_t = dev_priv->mem_freq; |
---|
216 | 227 | |
---|
217 | 228 | switch (csipll & 0x3ff) { |
---|
218 | 229 | case 0x00c: |
---|
.. | .. |
---|
237 | 248 | dev_priv->fsb_freq = 6400; |
---|
238 | 249 | break; |
---|
239 | 250 | default: |
---|
240 | | - DRM_DEBUG_DRIVER("unknown fsb frequency 0x%04x\n", |
---|
241 | | - csipll & 0x3ff); |
---|
| 251 | + drm_dbg(&dev_priv->drm, "unknown fsb frequency 0x%04x\n", |
---|
| 252 | + csipll & 0x3ff); |
---|
242 | 253 | dev_priv->fsb_freq = 0; |
---|
243 | 254 | break; |
---|
244 | | - } |
---|
245 | | - |
---|
246 | | - if (dev_priv->fsb_freq == 3200) { |
---|
247 | | - dev_priv->ips.c_m = 0; |
---|
248 | | - } else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) { |
---|
249 | | - dev_priv->ips.c_m = 1; |
---|
250 | | - } else { |
---|
251 | | - dev_priv->ips.c_m = 2; |
---|
252 | 255 | } |
---|
253 | 256 | } |
---|
254 | 257 | |
---|
.. | .. |
---|
318 | 321 | { |
---|
319 | 322 | u32 val; |
---|
320 | 323 | |
---|
321 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
| 324 | + vlv_punit_get(dev_priv); |
---|
322 | 325 | |
---|
323 | 326 | val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2); |
---|
324 | 327 | if (enable) |
---|
.. | .. |
---|
331 | 334 | |
---|
332 | 335 | if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) & |
---|
333 | 336 | FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) |
---|
334 | | - DRM_ERROR("timed out waiting for Punit DDR DVFS request\n"); |
---|
| 337 | + drm_err(&dev_priv->drm, |
---|
| 338 | + "timed out waiting for Punit DDR DVFS request\n"); |
---|
335 | 339 | |
---|
336 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
| 340 | + vlv_punit_put(dev_priv); |
---|
337 | 341 | } |
---|
338 | 342 | |
---|
339 | 343 | static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable) |
---|
340 | 344 | { |
---|
341 | 345 | u32 val; |
---|
342 | 346 | |
---|
343 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
| 347 | + vlv_punit_get(dev_priv); |
---|
344 | 348 | |
---|
345 | | - val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); |
---|
| 349 | + val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM); |
---|
346 | 350 | if (enable) |
---|
347 | 351 | val |= DSP_MAXFIFO_PM5_ENABLE; |
---|
348 | 352 | else |
---|
349 | 353 | val &= ~DSP_MAXFIFO_PM5_ENABLE; |
---|
350 | | - vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val); |
---|
| 354 | + vlv_punit_write(dev_priv, PUNIT_REG_DSPSSPM, val); |
---|
351 | 355 | |
---|
352 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
| 356 | + vlv_punit_put(dev_priv); |
---|
353 | 357 | } |
---|
354 | 358 | |
---|
355 | 359 | #define FW_WM(value, plane) \ |
---|
.. | .. |
---|
400 | 404 | |
---|
401 | 405 | trace_intel_memory_cxsr(dev_priv, was_enabled, enable); |
---|
402 | 406 | |
---|
403 | | - DRM_DEBUG_KMS("memory self-refresh is %s (was %s)\n", |
---|
404 | | - enableddisabled(enable), |
---|
405 | | - enableddisabled(was_enabled)); |
---|
| 407 | + drm_dbg_kms(&dev_priv->drm, "memory self-refresh is %s (was %s)\n", |
---|
| 408 | + enableddisabled(enable), |
---|
| 409 | + enableddisabled(was_enabled)); |
---|
406 | 410 | |
---|
407 | 411 | return was_enabled; |
---|
408 | 412 | } |
---|
.. | .. |
---|
480 | 484 | |
---|
481 | 485 | static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state) |
---|
482 | 486 | { |
---|
483 | | - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
---|
| 487 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
484 | 488 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
485 | 489 | struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state; |
---|
486 | 490 | enum pipe pipe = crtc->pipe; |
---|
487 | 491 | int sprite0_start, sprite1_start; |
---|
| 492 | + u32 dsparb, dsparb2, dsparb3; |
---|
488 | 493 | |
---|
489 | 494 | switch (pipe) { |
---|
490 | | - uint32_t dsparb, dsparb2, dsparb3; |
---|
491 | 495 | case PIPE_A: |
---|
492 | 496 | dsparb = I915_READ(DSPARB); |
---|
493 | 497 | dsparb2 = I915_READ(DSPARB2); |
---|
.. | .. |
---|
520 | 524 | static int i9xx_get_fifo_size(struct drm_i915_private *dev_priv, |
---|
521 | 525 | enum i9xx_plane_id i9xx_plane) |
---|
522 | 526 | { |
---|
523 | | - uint32_t dsparb = I915_READ(DSPARB); |
---|
| 527 | + u32 dsparb = I915_READ(DSPARB); |
---|
524 | 528 | int size; |
---|
525 | 529 | |
---|
526 | 530 | size = dsparb & 0x7f; |
---|
527 | 531 | if (i9xx_plane == PLANE_B) |
---|
528 | 532 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size; |
---|
529 | 533 | |
---|
530 | | - DRM_DEBUG_KMS("FIFO size - (0x%08x) %c: %d\n", |
---|
531 | | - dsparb, plane_name(i9xx_plane), size); |
---|
| 534 | + drm_dbg_kms(&dev_priv->drm, "FIFO size - (0x%08x) %c: %d\n", |
---|
| 535 | + dsparb, plane_name(i9xx_plane), size); |
---|
532 | 536 | |
---|
533 | 537 | return size; |
---|
534 | 538 | } |
---|
.. | .. |
---|
536 | 540 | static int i830_get_fifo_size(struct drm_i915_private *dev_priv, |
---|
537 | 541 | enum i9xx_plane_id i9xx_plane) |
---|
538 | 542 | { |
---|
539 | | - uint32_t dsparb = I915_READ(DSPARB); |
---|
| 543 | + u32 dsparb = I915_READ(DSPARB); |
---|
540 | 544 | int size; |
---|
541 | 545 | |
---|
542 | 546 | size = dsparb & 0x1ff; |
---|
.. | .. |
---|
544 | 548 | size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - size; |
---|
545 | 549 | size >>= 1; /* Convert to cachelines */ |
---|
546 | 550 | |
---|
547 | | - DRM_DEBUG_KMS("FIFO size - (0x%08x) %c: %d\n", |
---|
548 | | - dsparb, plane_name(i9xx_plane), size); |
---|
| 551 | + drm_dbg_kms(&dev_priv->drm, "FIFO size - (0x%08x) %c: %d\n", |
---|
| 552 | + dsparb, plane_name(i9xx_plane), size); |
---|
549 | 553 | |
---|
550 | 554 | return size; |
---|
551 | 555 | } |
---|
.. | .. |
---|
553 | 557 | static int i845_get_fifo_size(struct drm_i915_private *dev_priv, |
---|
554 | 558 | enum i9xx_plane_id i9xx_plane) |
---|
555 | 559 | { |
---|
556 | | - uint32_t dsparb = I915_READ(DSPARB); |
---|
| 560 | + u32 dsparb = I915_READ(DSPARB); |
---|
557 | 561 | int size; |
---|
558 | 562 | |
---|
559 | 563 | size = dsparb & 0x7f; |
---|
560 | 564 | size >>= 2; /* Convert to cachelines */ |
---|
561 | 565 | |
---|
562 | | - DRM_DEBUG_KMS("FIFO size - (0x%08x) %c: %d\n", |
---|
563 | | - dsparb, plane_name(i9xx_plane), size); |
---|
| 566 | + drm_dbg_kms(&dev_priv->drm, "FIFO size - (0x%08x) %c: %d\n", |
---|
| 567 | + dsparb, plane_name(i9xx_plane), size); |
---|
564 | 568 | |
---|
565 | 569 | return size; |
---|
566 | 570 | } |
---|
567 | 571 | |
---|
568 | 572 | /* Pineview has different values for various configs */ |
---|
569 | | -static const struct intel_watermark_params pineview_display_wm = { |
---|
| 573 | +static const struct intel_watermark_params pnv_display_wm = { |
---|
570 | 574 | .fifo_size = PINEVIEW_DISPLAY_FIFO, |
---|
571 | 575 | .max_wm = PINEVIEW_MAX_WM, |
---|
572 | 576 | .default_wm = PINEVIEW_DFT_WM, |
---|
573 | 577 | .guard_size = PINEVIEW_GUARD_WM, |
---|
574 | 578 | .cacheline_size = PINEVIEW_FIFO_LINE_SIZE, |
---|
575 | 579 | }; |
---|
576 | | -static const struct intel_watermark_params pineview_display_hplloff_wm = { |
---|
| 580 | + |
---|
| 581 | +static const struct intel_watermark_params pnv_display_hplloff_wm = { |
---|
577 | 582 | .fifo_size = PINEVIEW_DISPLAY_FIFO, |
---|
578 | 583 | .max_wm = PINEVIEW_MAX_WM, |
---|
579 | 584 | .default_wm = PINEVIEW_DFT_HPLLOFF_WM, |
---|
580 | 585 | .guard_size = PINEVIEW_GUARD_WM, |
---|
581 | 586 | .cacheline_size = PINEVIEW_FIFO_LINE_SIZE, |
---|
582 | 587 | }; |
---|
583 | | -static const struct intel_watermark_params pineview_cursor_wm = { |
---|
| 588 | + |
---|
| 589 | +static const struct intel_watermark_params pnv_cursor_wm = { |
---|
584 | 590 | .fifo_size = PINEVIEW_CURSOR_FIFO, |
---|
585 | 591 | .max_wm = PINEVIEW_CURSOR_MAX_WM, |
---|
586 | 592 | .default_wm = PINEVIEW_CURSOR_DFT_WM, |
---|
587 | 593 | .guard_size = PINEVIEW_CURSOR_GUARD_WM, |
---|
588 | 594 | .cacheline_size = PINEVIEW_FIFO_LINE_SIZE, |
---|
589 | 595 | }; |
---|
590 | | -static const struct intel_watermark_params pineview_cursor_hplloff_wm = { |
---|
| 596 | + |
---|
| 597 | +static const struct intel_watermark_params pnv_cursor_hplloff_wm = { |
---|
591 | 598 | .fifo_size = PINEVIEW_CURSOR_FIFO, |
---|
592 | 599 | .max_wm = PINEVIEW_CURSOR_MAX_WM, |
---|
593 | 600 | .default_wm = PINEVIEW_CURSOR_DFT_WM, |
---|
594 | 601 | .guard_size = PINEVIEW_CURSOR_GUARD_WM, |
---|
595 | 602 | .cacheline_size = PINEVIEW_FIFO_LINE_SIZE, |
---|
596 | 603 | }; |
---|
| 604 | + |
---|
597 | 605 | static const struct intel_watermark_params i965_cursor_wm_info = { |
---|
598 | 606 | .fifo_size = I965_CURSOR_FIFO, |
---|
599 | 607 | .max_wm = I965_CURSOR_MAX_WM, |
---|
.. | .. |
---|
601 | 609 | .guard_size = 2, |
---|
602 | 610 | .cacheline_size = I915_FIFO_LINE_SIZE, |
---|
603 | 611 | }; |
---|
| 612 | + |
---|
604 | 613 | static const struct intel_watermark_params i945_wm_info = { |
---|
605 | 614 | .fifo_size = I945_FIFO_SIZE, |
---|
606 | 615 | .max_wm = I915_MAX_WM, |
---|
.. | .. |
---|
608 | 617 | .guard_size = 2, |
---|
609 | 618 | .cacheline_size = I915_FIFO_LINE_SIZE, |
---|
610 | 619 | }; |
---|
| 620 | + |
---|
611 | 621 | static const struct intel_watermark_params i915_wm_info = { |
---|
612 | 622 | .fifo_size = I915_FIFO_SIZE, |
---|
613 | 623 | .max_wm = I915_MAX_WM, |
---|
.. | .. |
---|
615 | 625 | .guard_size = 2, |
---|
616 | 626 | .cacheline_size = I915_FIFO_LINE_SIZE, |
---|
617 | 627 | }; |
---|
| 628 | + |
---|
618 | 629 | static const struct intel_watermark_params i830_a_wm_info = { |
---|
619 | 630 | .fifo_size = I855GM_FIFO_SIZE, |
---|
620 | 631 | .max_wm = I915_MAX_WM, |
---|
.. | .. |
---|
622 | 633 | .guard_size = 2, |
---|
623 | 634 | .cacheline_size = I830_FIFO_LINE_SIZE, |
---|
624 | 635 | }; |
---|
| 636 | + |
---|
625 | 637 | static const struct intel_watermark_params i830_bc_wm_info = { |
---|
626 | 638 | .fifo_size = I855GM_FIFO_SIZE, |
---|
627 | 639 | .max_wm = I915_MAX_WM/2, |
---|
.. | .. |
---|
629 | 641 | .guard_size = 2, |
---|
630 | 642 | .cacheline_size = I830_FIFO_LINE_SIZE, |
---|
631 | 643 | }; |
---|
| 644 | + |
---|
632 | 645 | static const struct intel_watermark_params i845_wm_info = { |
---|
633 | 646 | .fifo_size = I830_FIFO_SIZE, |
---|
634 | 647 | .max_wm = I915_MAX_WM, |
---|
.. | .. |
---|
674 | 687 | unsigned int cpp, |
---|
675 | 688 | unsigned int latency) |
---|
676 | 689 | { |
---|
677 | | - uint64_t ret; |
---|
| 690 | + u64 ret; |
---|
678 | 691 | |
---|
679 | | - ret = (uint64_t) pixel_rate * cpp * latency; |
---|
| 692 | + ret = mul_u32_u32(pixel_rate, cpp * latency); |
---|
680 | 693 | ret = DIV_ROUND_UP_ULL(ret, 10000); |
---|
681 | 694 | |
---|
682 | 695 | return ret; |
---|
.. | .. |
---|
811 | 824 | static bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state, |
---|
812 | 825 | const struct intel_plane_state *plane_state) |
---|
813 | 826 | { |
---|
814 | | - struct intel_plane *plane = to_intel_plane(plane_state->base.plane); |
---|
| 827 | + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); |
---|
815 | 828 | |
---|
816 | 829 | /* FIXME check the 'enable' instead */ |
---|
817 | | - if (!crtc_state->base.active) |
---|
| 830 | + if (!crtc_state->hw.active) |
---|
818 | 831 | return false; |
---|
819 | 832 | |
---|
820 | 833 | /* |
---|
.. | .. |
---|
826 | 839 | * around this problem with the watermark code. |
---|
827 | 840 | */ |
---|
828 | 841 | if (plane->id == PLANE_CURSOR) |
---|
829 | | - return plane_state->base.fb != NULL; |
---|
| 842 | + return plane_state->hw.fb != NULL; |
---|
830 | 843 | else |
---|
831 | | - return plane_state->base.visible; |
---|
| 844 | + return plane_state->uapi.visible; |
---|
| 845 | +} |
---|
| 846 | + |
---|
| 847 | +static bool intel_crtc_active(struct intel_crtc *crtc) |
---|
| 848 | +{ |
---|
| 849 | + /* Be paranoid as we can arrive here with only partial |
---|
| 850 | + * state retrieved from the hardware during setup. |
---|
| 851 | + * |
---|
| 852 | + * We can ditch the adjusted_mode.crtc_clock check as soon |
---|
| 853 | + * as Haswell has gained clock readout/fastboot support. |
---|
| 854 | + * |
---|
| 855 | + * We can ditch the crtc->primary->state->fb check as soon as we can |
---|
| 856 | + * properly reconstruct framebuffers. |
---|
| 857 | + * |
---|
| 858 | + * FIXME: The intel_crtc->active here should be switched to |
---|
| 859 | + * crtc->state->active once we have proper CRTC states wired up |
---|
| 860 | + * for atomic. |
---|
| 861 | + */ |
---|
| 862 | + return crtc->active && crtc->base.primary->state->fb && |
---|
| 863 | + crtc->config->hw.adjusted_mode.crtc_clock; |
---|
832 | 864 | } |
---|
833 | 865 | |
---|
834 | 866 | static struct intel_crtc *single_enabled_crtc(struct drm_i915_private *dev_priv) |
---|
.. | .. |
---|
846 | 878 | return enabled; |
---|
847 | 879 | } |
---|
848 | 880 | |
---|
849 | | -static void pineview_update_wm(struct intel_crtc *unused_crtc) |
---|
| 881 | +static void pnv_update_wm(struct intel_crtc *unused_crtc) |
---|
850 | 882 | { |
---|
851 | 883 | struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev); |
---|
852 | 884 | struct intel_crtc *crtc; |
---|
.. | .. |
---|
854 | 886 | u32 reg; |
---|
855 | 887 | unsigned int wm; |
---|
856 | 888 | |
---|
857 | | - latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev_priv), |
---|
| 889 | + latency = intel_get_cxsr_latency(!IS_MOBILE(dev_priv), |
---|
858 | 890 | dev_priv->is_ddr3, |
---|
859 | 891 | dev_priv->fsb_freq, |
---|
860 | 892 | dev_priv->mem_freq); |
---|
861 | 893 | if (!latency) { |
---|
862 | | - DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
---|
| 894 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 895 | + "Unknown FSB/MEM found, disable CxSR\n"); |
---|
863 | 896 | intel_set_memory_cxsr(dev_priv, false); |
---|
864 | 897 | return; |
---|
865 | 898 | } |
---|
.. | .. |
---|
867 | 900 | crtc = single_enabled_crtc(dev_priv); |
---|
868 | 901 | if (crtc) { |
---|
869 | 902 | const struct drm_display_mode *adjusted_mode = |
---|
870 | | - &crtc->config->base.adjusted_mode; |
---|
| 903 | + &crtc->config->hw.adjusted_mode; |
---|
871 | 904 | const struct drm_framebuffer *fb = |
---|
872 | 905 | crtc->base.primary->state->fb; |
---|
873 | 906 | int cpp = fb->format->cpp[0]; |
---|
874 | 907 | int clock = adjusted_mode->crtc_clock; |
---|
875 | 908 | |
---|
876 | 909 | /* Display SR */ |
---|
877 | | - wm = intel_calculate_wm(clock, &pineview_display_wm, |
---|
878 | | - pineview_display_wm.fifo_size, |
---|
| 910 | + wm = intel_calculate_wm(clock, &pnv_display_wm, |
---|
| 911 | + pnv_display_wm.fifo_size, |
---|
879 | 912 | cpp, latency->display_sr); |
---|
880 | 913 | reg = I915_READ(DSPFW1); |
---|
881 | 914 | reg &= ~DSPFW_SR_MASK; |
---|
882 | 915 | reg |= FW_WM(wm, SR); |
---|
883 | 916 | I915_WRITE(DSPFW1, reg); |
---|
884 | | - DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); |
---|
| 917 | + drm_dbg_kms(&dev_priv->drm, "DSPFW1 register is %x\n", reg); |
---|
885 | 918 | |
---|
886 | 919 | /* cursor SR */ |
---|
887 | | - wm = intel_calculate_wm(clock, &pineview_cursor_wm, |
---|
888 | | - pineview_display_wm.fifo_size, |
---|
| 920 | + wm = intel_calculate_wm(clock, &pnv_cursor_wm, |
---|
| 921 | + pnv_display_wm.fifo_size, |
---|
889 | 922 | 4, latency->cursor_sr); |
---|
890 | 923 | reg = I915_READ(DSPFW3); |
---|
891 | 924 | reg &= ~DSPFW_CURSOR_SR_MASK; |
---|
.. | .. |
---|
893 | 926 | I915_WRITE(DSPFW3, reg); |
---|
894 | 927 | |
---|
895 | 928 | /* Display HPLL off SR */ |
---|
896 | | - wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm, |
---|
897 | | - pineview_display_hplloff_wm.fifo_size, |
---|
| 929 | + wm = intel_calculate_wm(clock, &pnv_display_hplloff_wm, |
---|
| 930 | + pnv_display_hplloff_wm.fifo_size, |
---|
898 | 931 | cpp, latency->display_hpll_disable); |
---|
899 | 932 | reg = I915_READ(DSPFW3); |
---|
900 | 933 | reg &= ~DSPFW_HPLL_SR_MASK; |
---|
.. | .. |
---|
902 | 935 | I915_WRITE(DSPFW3, reg); |
---|
903 | 936 | |
---|
904 | 937 | /* cursor HPLL off SR */ |
---|
905 | | - wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, |
---|
906 | | - pineview_display_hplloff_wm.fifo_size, |
---|
| 938 | + wm = intel_calculate_wm(clock, &pnv_cursor_hplloff_wm, |
---|
| 939 | + pnv_display_hplloff_wm.fifo_size, |
---|
907 | 940 | 4, latency->cursor_hpll_disable); |
---|
908 | 941 | reg = I915_READ(DSPFW3); |
---|
909 | 942 | reg &= ~DSPFW_HPLL_CURSOR_MASK; |
---|
910 | 943 | reg |= FW_WM(wm, HPLL_CURSOR); |
---|
911 | 944 | I915_WRITE(DSPFW3, reg); |
---|
912 | | - DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); |
---|
| 945 | + drm_dbg_kms(&dev_priv->drm, "DSPFW3 register is %x\n", reg); |
---|
913 | 946 | |
---|
914 | 947 | intel_set_memory_cxsr(dev_priv, true); |
---|
915 | 948 | } else { |
---|
.. | .. |
---|
1096 | 1129 | } |
---|
1097 | 1130 | } |
---|
1098 | 1131 | |
---|
1099 | | -static uint16_t g4x_compute_wm(const struct intel_crtc_state *crtc_state, |
---|
1100 | | - const struct intel_plane_state *plane_state, |
---|
1101 | | - int level) |
---|
| 1132 | +static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state, |
---|
| 1133 | + const struct intel_plane_state *plane_state, |
---|
| 1134 | + int level) |
---|
1102 | 1135 | { |
---|
1103 | | - struct intel_plane *plane = to_intel_plane(plane_state->base.plane); |
---|
| 1136 | + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); |
---|
1104 | 1137 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
---|
1105 | 1138 | const struct drm_display_mode *adjusted_mode = |
---|
1106 | | - &crtc_state->base.adjusted_mode; |
---|
| 1139 | + &crtc_state->hw.adjusted_mode; |
---|
1107 | 1140 | unsigned int latency = dev_priv->wm.pri_latency[level] * 10; |
---|
1108 | 1141 | unsigned int clock, htotal, cpp, width, wm; |
---|
1109 | 1142 | |
---|
.. | .. |
---|
1112 | 1145 | |
---|
1113 | 1146 | if (!intel_wm_plane_visible(crtc_state, plane_state)) |
---|
1114 | 1147 | return 0; |
---|
| 1148 | + |
---|
| 1149 | + cpp = plane_state->hw.fb->format->cpp[0]; |
---|
1115 | 1150 | |
---|
1116 | 1151 | /* |
---|
1117 | 1152 | * Not 100% sure which way ELK should go here as the |
---|
.. | .. |
---|
1126 | 1161 | */ |
---|
1127 | 1162 | if (IS_GM45(dev_priv) && plane->id == PLANE_PRIMARY && |
---|
1128 | 1163 | level != G4X_WM_LEVEL_NORMAL) |
---|
1129 | | - cpp = 4; |
---|
1130 | | - else |
---|
1131 | | - cpp = plane_state->base.fb->format->cpp[0]; |
---|
| 1164 | + cpp = max(cpp, 4u); |
---|
1132 | 1165 | |
---|
1133 | 1166 | clock = adjusted_mode->crtc_clock; |
---|
1134 | 1167 | htotal = adjusted_mode->crtc_htotal; |
---|
1135 | 1168 | |
---|
1136 | | - if (plane->id == PLANE_CURSOR) |
---|
1137 | | - width = plane_state->base.crtc_w; |
---|
1138 | | - else |
---|
1139 | | - width = drm_rect_width(&plane_state->base.dst); |
---|
| 1169 | + width = drm_rect_width(&plane_state->uapi.dst); |
---|
1140 | 1170 | |
---|
1141 | 1171 | if (plane->id == PLANE_CURSOR) { |
---|
1142 | 1172 | wm = intel_wm_method2(clock, htotal, width, cpp, latency); |
---|
.. | .. |
---|
1163 | 1193 | static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state, |
---|
1164 | 1194 | int level, enum plane_id plane_id, u16 value) |
---|
1165 | 1195 | { |
---|
1166 | | - struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); |
---|
| 1196 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
1167 | 1197 | bool dirty = false; |
---|
1168 | 1198 | |
---|
1169 | 1199 | for (; level < intel_wm_num_levels(dev_priv); level++) { |
---|
.. | .. |
---|
1179 | 1209 | static bool g4x_raw_fbc_wm_set(struct intel_crtc_state *crtc_state, |
---|
1180 | 1210 | int level, u16 value) |
---|
1181 | 1211 | { |
---|
1182 | | - struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); |
---|
| 1212 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
1183 | 1213 | bool dirty = false; |
---|
1184 | 1214 | |
---|
1185 | 1215 | /* NORMAL level doesn't have an FBC watermark */ |
---|
.. | .. |
---|
1195 | 1225 | return dirty; |
---|
1196 | 1226 | } |
---|
1197 | 1227 | |
---|
1198 | | -static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate, |
---|
1199 | | - const struct intel_plane_state *pstate, |
---|
1200 | | - uint32_t pri_val); |
---|
| 1228 | +static u32 ilk_compute_fbc_wm(const struct intel_crtc_state *crtc_state, |
---|
| 1229 | + const struct intel_plane_state *plane_state, |
---|
| 1230 | + u32 pri_val); |
---|
1201 | 1231 | |
---|
1202 | 1232 | static bool g4x_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, |
---|
1203 | 1233 | const struct intel_plane_state *plane_state) |
---|
1204 | 1234 | { |
---|
1205 | | - struct intel_plane *plane = to_intel_plane(plane_state->base.plane); |
---|
| 1235 | + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); |
---|
| 1236 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
1206 | 1237 | int num_levels = intel_wm_num_levels(to_i915(plane->base.dev)); |
---|
1207 | 1238 | enum plane_id plane_id = plane->id; |
---|
1208 | 1239 | bool dirty = false; |
---|
.. | .. |
---|
1255 | 1286 | |
---|
1256 | 1287 | out: |
---|
1257 | 1288 | if (dirty) { |
---|
1258 | | - DRM_DEBUG_KMS("%s watermarks: normal=%d, SR=%d, HPLL=%d\n", |
---|
1259 | | - plane->base.name, |
---|
1260 | | - crtc_state->wm.g4x.raw[G4X_WM_LEVEL_NORMAL].plane[plane_id], |
---|
1261 | | - crtc_state->wm.g4x.raw[G4X_WM_LEVEL_SR].plane[plane_id], |
---|
1262 | | - crtc_state->wm.g4x.raw[G4X_WM_LEVEL_HPLL].plane[plane_id]); |
---|
| 1289 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 1290 | + "%s watermarks: normal=%d, SR=%d, HPLL=%d\n", |
---|
| 1291 | + plane->base.name, |
---|
| 1292 | + crtc_state->wm.g4x.raw[G4X_WM_LEVEL_NORMAL].plane[plane_id], |
---|
| 1293 | + crtc_state->wm.g4x.raw[G4X_WM_LEVEL_SR].plane[plane_id], |
---|
| 1294 | + crtc_state->wm.g4x.raw[G4X_WM_LEVEL_HPLL].plane[plane_id]); |
---|
1263 | 1295 | |
---|
1264 | 1296 | if (plane_id == PLANE_PRIMARY) |
---|
1265 | | - DRM_DEBUG_KMS("FBC watermarks: SR=%d, HPLL=%d\n", |
---|
1266 | | - crtc_state->wm.g4x.raw[G4X_WM_LEVEL_SR].fbc, |
---|
1267 | | - crtc_state->wm.g4x.raw[G4X_WM_LEVEL_HPLL].fbc); |
---|
| 1297 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 1298 | + "FBC watermarks: SR=%d, HPLL=%d\n", |
---|
| 1299 | + crtc_state->wm.g4x.raw[G4X_WM_LEVEL_SR].fbc, |
---|
| 1300 | + crtc_state->wm.g4x.raw[G4X_WM_LEVEL_HPLL].fbc); |
---|
1268 | 1301 | } |
---|
1269 | 1302 | |
---|
1270 | 1303 | return dirty; |
---|
.. | .. |
---|
1281 | 1314 | static bool g4x_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state, |
---|
1282 | 1315 | int level) |
---|
1283 | 1316 | { |
---|
1284 | | - struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); |
---|
| 1317 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
1285 | 1318 | |
---|
1286 | 1319 | if (level > dev_priv->wm.max_level) |
---|
1287 | 1320 | return false; |
---|
.. | .. |
---|
1317 | 1350 | } |
---|
1318 | 1351 | } |
---|
1319 | 1352 | |
---|
| 1353 | +static bool g4x_compute_fbc_en(const struct g4x_wm_state *wm_state, |
---|
| 1354 | + int level) |
---|
| 1355 | +{ |
---|
| 1356 | + if (level < G4X_WM_LEVEL_SR) |
---|
| 1357 | + return false; |
---|
| 1358 | + |
---|
| 1359 | + if (level >= G4X_WM_LEVEL_SR && |
---|
| 1360 | + wm_state->sr.fbc > g4x_fbc_fifo_size(G4X_WM_LEVEL_SR)) |
---|
| 1361 | + return false; |
---|
| 1362 | + |
---|
| 1363 | + if (level >= G4X_WM_LEVEL_HPLL && |
---|
| 1364 | + wm_state->hpll.fbc > g4x_fbc_fifo_size(G4X_WM_LEVEL_HPLL)) |
---|
| 1365 | + return false; |
---|
| 1366 | + |
---|
| 1367 | + return true; |
---|
| 1368 | +} |
---|
| 1369 | + |
---|
1320 | 1370 | static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state) |
---|
1321 | 1371 | { |
---|
1322 | | - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
---|
| 1372 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
1323 | 1373 | struct intel_atomic_state *state = |
---|
1324 | | - to_intel_atomic_state(crtc_state->base.state); |
---|
| 1374 | + to_intel_atomic_state(crtc_state->uapi.state); |
---|
1325 | 1375 | struct g4x_wm_state *wm_state = &crtc_state->wm.g4x.optimal; |
---|
1326 | | - int num_active_planes = hweight32(crtc_state->active_planes & |
---|
1327 | | - ~BIT(PLANE_CURSOR)); |
---|
| 1376 | + int num_active_planes = hweight8(crtc_state->active_planes & |
---|
| 1377 | + ~BIT(PLANE_CURSOR)); |
---|
1328 | 1378 | const struct g4x_pipe_wm *raw; |
---|
1329 | 1379 | const struct intel_plane_state *old_plane_state; |
---|
1330 | 1380 | const struct intel_plane_state *new_plane_state; |
---|
.. | .. |
---|
1336 | 1386 | for_each_oldnew_intel_plane_in_state(state, plane, |
---|
1337 | 1387 | old_plane_state, |
---|
1338 | 1388 | new_plane_state, i) { |
---|
1339 | | - if (new_plane_state->base.crtc != &crtc->base && |
---|
1340 | | - old_plane_state->base.crtc != &crtc->base) |
---|
| 1389 | + if (new_plane_state->hw.crtc != &crtc->base && |
---|
| 1390 | + old_plane_state->hw.crtc != &crtc->base) |
---|
1341 | 1391 | continue; |
---|
1342 | 1392 | |
---|
1343 | 1393 | if (g4x_raw_plane_wm_compute(crtc_state, new_plane_state)) |
---|
.. | .. |
---|
1356 | 1406 | wm_state->wm.plane[plane_id] = raw->plane[plane_id]; |
---|
1357 | 1407 | |
---|
1358 | 1408 | level = G4X_WM_LEVEL_SR; |
---|
1359 | | - |
---|
1360 | 1409 | if (!g4x_raw_crtc_wm_is_valid(crtc_state, level)) |
---|
1361 | 1410 | goto out; |
---|
1362 | 1411 | |
---|
.. | .. |
---|
1368 | 1417 | wm_state->cxsr = num_active_planes == BIT(PLANE_PRIMARY); |
---|
1369 | 1418 | |
---|
1370 | 1419 | level = G4X_WM_LEVEL_HPLL; |
---|
1371 | | - |
---|
1372 | 1420 | if (!g4x_raw_crtc_wm_is_valid(crtc_state, level)) |
---|
1373 | 1421 | goto out; |
---|
1374 | 1422 | |
---|
.. | .. |
---|
1391 | 1439 | /* |
---|
1392 | 1440 | * Determine if the FBC watermark(s) can be used. IF |
---|
1393 | 1441 | * this isn't the case we prefer to disable the FBC |
---|
1394 | | - ( watermark(s) rather than disable the SR/HPLL |
---|
1395 | | - * level(s) entirely. |
---|
| 1442 | + * watermark(s) rather than disable the SR/HPLL |
---|
| 1443 | + * level(s) entirely. 'level-1' is the highest valid |
---|
| 1444 | + * level here. |
---|
1396 | 1445 | */ |
---|
1397 | | - wm_state->fbc_en = level > G4X_WM_LEVEL_NORMAL; |
---|
1398 | | - |
---|
1399 | | - if (level >= G4X_WM_LEVEL_SR && |
---|
1400 | | - wm_state->sr.fbc > g4x_fbc_fifo_size(G4X_WM_LEVEL_SR)) |
---|
1401 | | - wm_state->fbc_en = false; |
---|
1402 | | - else if (level >= G4X_WM_LEVEL_HPLL && |
---|
1403 | | - wm_state->hpll.fbc > g4x_fbc_fifo_size(G4X_WM_LEVEL_HPLL)) |
---|
1404 | | - wm_state->fbc_en = false; |
---|
| 1446 | + wm_state->fbc_en = g4x_compute_fbc_en(wm_state, level - 1); |
---|
1405 | 1447 | |
---|
1406 | 1448 | return 0; |
---|
1407 | 1449 | } |
---|
1408 | 1450 | |
---|
1409 | | -static int g4x_compute_intermediate_wm(struct drm_device *dev, |
---|
1410 | | - struct intel_crtc *crtc, |
---|
1411 | | - struct intel_crtc_state *new_crtc_state) |
---|
| 1451 | +static int g4x_compute_intermediate_wm(struct intel_crtc_state *new_crtc_state) |
---|
1412 | 1452 | { |
---|
| 1453 | + struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); |
---|
| 1454 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
1413 | 1455 | struct g4x_wm_state *intermediate = &new_crtc_state->wm.g4x.intermediate; |
---|
1414 | 1456 | const struct g4x_wm_state *optimal = &new_crtc_state->wm.g4x.optimal; |
---|
1415 | 1457 | struct intel_atomic_state *intel_state = |
---|
1416 | | - to_intel_atomic_state(new_crtc_state->base.state); |
---|
| 1458 | + to_intel_atomic_state(new_crtc_state->uapi.state); |
---|
1417 | 1459 | const struct intel_crtc_state *old_crtc_state = |
---|
1418 | 1460 | intel_atomic_get_old_crtc_state(intel_state, crtc); |
---|
1419 | 1461 | const struct g4x_wm_state *active = &old_crtc_state->wm.g4x.optimal; |
---|
1420 | 1462 | enum plane_id plane_id; |
---|
1421 | 1463 | |
---|
1422 | | - if (!new_crtc_state->base.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->base)) { |
---|
| 1464 | + if (!new_crtc_state->hw.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi)) { |
---|
1423 | 1465 | *intermediate = *optimal; |
---|
1424 | 1466 | |
---|
1425 | 1467 | intermediate->cxsr = false; |
---|
.. | .. |
---|
1438 | 1480 | max(optimal->wm.plane[plane_id], |
---|
1439 | 1481 | active->wm.plane[plane_id]); |
---|
1440 | 1482 | |
---|
1441 | | - WARN_ON(intermediate->wm.plane[plane_id] > |
---|
1442 | | - g4x_plane_fifo_size(plane_id, G4X_WM_LEVEL_NORMAL)); |
---|
| 1483 | + drm_WARN_ON(&dev_priv->drm, intermediate->wm.plane[plane_id] > |
---|
| 1484 | + g4x_plane_fifo_size(plane_id, G4X_WM_LEVEL_NORMAL)); |
---|
1443 | 1485 | } |
---|
1444 | 1486 | |
---|
1445 | 1487 | intermediate->sr.plane = max(optimal->sr.plane, |
---|
.. | .. |
---|
1456 | 1498 | intermediate->hpll.fbc = max(optimal->hpll.fbc, |
---|
1457 | 1499 | active->hpll.fbc); |
---|
1458 | 1500 | |
---|
1459 | | - WARN_ON((intermediate->sr.plane > |
---|
1460 | | - g4x_plane_fifo_size(PLANE_PRIMARY, G4X_WM_LEVEL_SR) || |
---|
1461 | | - intermediate->sr.cursor > |
---|
1462 | | - g4x_plane_fifo_size(PLANE_CURSOR, G4X_WM_LEVEL_SR)) && |
---|
1463 | | - intermediate->cxsr); |
---|
1464 | | - WARN_ON((intermediate->sr.plane > |
---|
1465 | | - g4x_plane_fifo_size(PLANE_PRIMARY, G4X_WM_LEVEL_HPLL) || |
---|
1466 | | - intermediate->sr.cursor > |
---|
1467 | | - g4x_plane_fifo_size(PLANE_CURSOR, G4X_WM_LEVEL_HPLL)) && |
---|
1468 | | - intermediate->hpll_en); |
---|
| 1501 | + drm_WARN_ON(&dev_priv->drm, |
---|
| 1502 | + (intermediate->sr.plane > |
---|
| 1503 | + g4x_plane_fifo_size(PLANE_PRIMARY, G4X_WM_LEVEL_SR) || |
---|
| 1504 | + intermediate->sr.cursor > |
---|
| 1505 | + g4x_plane_fifo_size(PLANE_CURSOR, G4X_WM_LEVEL_SR)) && |
---|
| 1506 | + intermediate->cxsr); |
---|
| 1507 | + drm_WARN_ON(&dev_priv->drm, |
---|
| 1508 | + (intermediate->sr.plane > |
---|
| 1509 | + g4x_plane_fifo_size(PLANE_PRIMARY, G4X_WM_LEVEL_HPLL) || |
---|
| 1510 | + intermediate->sr.cursor > |
---|
| 1511 | + g4x_plane_fifo_size(PLANE_CURSOR, G4X_WM_LEVEL_HPLL)) && |
---|
| 1512 | + intermediate->hpll_en); |
---|
1469 | 1513 | |
---|
1470 | | - WARN_ON(intermediate->sr.fbc > g4x_fbc_fifo_size(1) && |
---|
1471 | | - intermediate->fbc_en && intermediate->cxsr); |
---|
1472 | | - WARN_ON(intermediate->hpll.fbc > g4x_fbc_fifo_size(2) && |
---|
1473 | | - intermediate->fbc_en && intermediate->hpll_en); |
---|
| 1514 | + drm_WARN_ON(&dev_priv->drm, |
---|
| 1515 | + intermediate->sr.fbc > g4x_fbc_fifo_size(1) && |
---|
| 1516 | + intermediate->fbc_en && intermediate->cxsr); |
---|
| 1517 | + drm_WARN_ON(&dev_priv->drm, |
---|
| 1518 | + intermediate->hpll.fbc > g4x_fbc_fifo_size(2) && |
---|
| 1519 | + intermediate->fbc_en && intermediate->hpll_en); |
---|
1474 | 1520 | |
---|
1475 | 1521 | out: |
---|
1476 | 1522 | /* |
---|
.. | .. |
---|
1487 | 1533 | struct g4x_wm_values *wm) |
---|
1488 | 1534 | { |
---|
1489 | 1535 | struct intel_crtc *crtc; |
---|
1490 | | - int num_active_crtcs = 0; |
---|
| 1536 | + int num_active_pipes = 0; |
---|
1491 | 1537 | |
---|
1492 | 1538 | wm->cxsr = true; |
---|
1493 | 1539 | wm->hpll_en = true; |
---|
.. | .. |
---|
1506 | 1552 | if (!wm_state->fbc_en) |
---|
1507 | 1553 | wm->fbc_en = false; |
---|
1508 | 1554 | |
---|
1509 | | - num_active_crtcs++; |
---|
| 1555 | + num_active_pipes++; |
---|
1510 | 1556 | } |
---|
1511 | 1557 | |
---|
1512 | | - if (num_active_crtcs != 1) { |
---|
| 1558 | + if (num_active_pipes != 1) { |
---|
1513 | 1559 | wm->cxsr = false; |
---|
1514 | 1560 | wm->hpll_en = false; |
---|
1515 | 1561 | wm->fbc_en = false; |
---|
.. | .. |
---|
1549 | 1595 | } |
---|
1550 | 1596 | |
---|
1551 | 1597 | static void g4x_initial_watermarks(struct intel_atomic_state *state, |
---|
1552 | | - struct intel_crtc_state *crtc_state) |
---|
| 1598 | + struct intel_crtc *crtc) |
---|
1553 | 1599 | { |
---|
1554 | | - struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); |
---|
1555 | | - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
---|
| 1600 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 1601 | + const struct intel_crtc_state *crtc_state = |
---|
| 1602 | + intel_atomic_get_new_crtc_state(state, crtc); |
---|
1556 | 1603 | |
---|
1557 | 1604 | mutex_lock(&dev_priv->wm.wm_mutex); |
---|
1558 | 1605 | crtc->wm.active.g4x = crtc_state->wm.g4x.intermediate; |
---|
.. | .. |
---|
1561 | 1608 | } |
---|
1562 | 1609 | |
---|
1563 | 1610 | static void g4x_optimize_watermarks(struct intel_atomic_state *state, |
---|
1564 | | - struct intel_crtc_state *crtc_state) |
---|
| 1611 | + struct intel_crtc *crtc) |
---|
1565 | 1612 | { |
---|
1566 | | - struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); |
---|
1567 | | - struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); |
---|
| 1613 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 1614 | + const struct intel_crtc_state *crtc_state = |
---|
| 1615 | + intel_atomic_get_new_crtc_state(state, crtc); |
---|
1568 | 1616 | |
---|
1569 | 1617 | if (!crtc_state->wm.need_postvbl_update) |
---|
1570 | 1618 | return; |
---|
1571 | 1619 | |
---|
1572 | 1620 | mutex_lock(&dev_priv->wm.wm_mutex); |
---|
1573 | | - intel_crtc->wm.active.g4x = crtc_state->wm.g4x.optimal; |
---|
| 1621 | + crtc->wm.active.g4x = crtc_state->wm.g4x.optimal; |
---|
1574 | 1622 | g4x_program_watermarks(dev_priv); |
---|
1575 | 1623 | mutex_unlock(&dev_priv->wm.wm_mutex); |
---|
1576 | 1624 | } |
---|
.. | .. |
---|
1606 | 1654 | } |
---|
1607 | 1655 | } |
---|
1608 | 1656 | |
---|
1609 | | -static uint16_t vlv_compute_wm_level(const struct intel_crtc_state *crtc_state, |
---|
1610 | | - const struct intel_plane_state *plane_state, |
---|
1611 | | - int level) |
---|
| 1657 | +static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state, |
---|
| 1658 | + const struct intel_plane_state *plane_state, |
---|
| 1659 | + int level) |
---|
1612 | 1660 | { |
---|
1613 | | - struct intel_plane *plane = to_intel_plane(plane_state->base.plane); |
---|
| 1661 | + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); |
---|
1614 | 1662 | struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
---|
1615 | 1663 | const struct drm_display_mode *adjusted_mode = |
---|
1616 | | - &crtc_state->base.adjusted_mode; |
---|
| 1664 | + &crtc_state->hw.adjusted_mode; |
---|
1617 | 1665 | unsigned int clock, htotal, cpp, width, wm; |
---|
1618 | 1666 | |
---|
1619 | 1667 | if (dev_priv->wm.pri_latency[level] == 0) |
---|
.. | .. |
---|
1622 | 1670 | if (!intel_wm_plane_visible(crtc_state, plane_state)) |
---|
1623 | 1671 | return 0; |
---|
1624 | 1672 | |
---|
1625 | | - cpp = plane_state->base.fb->format->cpp[0]; |
---|
| 1673 | + cpp = plane_state->hw.fb->format->cpp[0]; |
---|
1626 | 1674 | clock = adjusted_mode->crtc_clock; |
---|
1627 | 1675 | htotal = adjusted_mode->crtc_htotal; |
---|
1628 | 1676 | width = crtc_state->pipe_src_w; |
---|
.. | .. |
---|
1651 | 1699 | |
---|
1652 | 1700 | static int vlv_compute_fifo(struct intel_crtc_state *crtc_state) |
---|
1653 | 1701 | { |
---|
1654 | | - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
---|
| 1702 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
| 1703 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
1655 | 1704 | const struct g4x_pipe_wm *raw = |
---|
1656 | 1705 | &crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2]; |
---|
1657 | 1706 | struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state; |
---|
1658 | 1707 | unsigned int active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); |
---|
1659 | | - int num_active_planes = hweight32(active_planes); |
---|
| 1708 | + int num_active_planes = hweight8(active_planes); |
---|
1660 | 1709 | const int fifo_size = 511; |
---|
1661 | 1710 | int fifo_extra, fifo_left = fifo_size; |
---|
1662 | 1711 | int sprite0_fifo_extra = 0; |
---|
.. | .. |
---|
1720 | 1769 | fifo_left -= plane_extra; |
---|
1721 | 1770 | } |
---|
1722 | 1771 | |
---|
1723 | | - WARN_ON(active_planes != 0 && fifo_left != 0); |
---|
| 1772 | + drm_WARN_ON(&dev_priv->drm, active_planes != 0 && fifo_left != 0); |
---|
1724 | 1773 | |
---|
1725 | 1774 | /* give it all to the first plane if none are active */ |
---|
1726 | 1775 | if (active_planes == 0) { |
---|
1727 | | - WARN_ON(fifo_left != fifo_size); |
---|
| 1776 | + drm_WARN_ON(&dev_priv->drm, fifo_left != fifo_size); |
---|
1728 | 1777 | fifo_state->plane[PLANE_PRIMARY] = fifo_left; |
---|
1729 | 1778 | } |
---|
1730 | 1779 | |
---|
.. | .. |
---|
1763 | 1812 | static bool vlv_raw_plane_wm_set(struct intel_crtc_state *crtc_state, |
---|
1764 | 1813 | int level, enum plane_id plane_id, u16 value) |
---|
1765 | 1814 | { |
---|
1766 | | - struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); |
---|
| 1815 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
1767 | 1816 | int num_levels = intel_wm_num_levels(dev_priv); |
---|
1768 | 1817 | bool dirty = false; |
---|
1769 | 1818 | |
---|
.. | .. |
---|
1780 | 1829 | static bool vlv_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, |
---|
1781 | 1830 | const struct intel_plane_state *plane_state) |
---|
1782 | 1831 | { |
---|
1783 | | - struct intel_plane *plane = to_intel_plane(plane_state->base.plane); |
---|
| 1832 | + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); |
---|
| 1833 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
1784 | 1834 | enum plane_id plane_id = plane->id; |
---|
1785 | 1835 | int num_levels = intel_wm_num_levels(to_i915(plane->base.dev)); |
---|
1786 | 1836 | int level; |
---|
.. | .. |
---|
1808 | 1858 | |
---|
1809 | 1859 | out: |
---|
1810 | 1860 | if (dirty) |
---|
1811 | | - DRM_DEBUG_KMS("%s watermarks: PM2=%d, PM5=%d, DDR DVFS=%d\n", |
---|
1812 | | - plane->base.name, |
---|
1813 | | - crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2].plane[plane_id], |
---|
1814 | | - crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM5].plane[plane_id], |
---|
1815 | | - crtc_state->wm.vlv.raw[VLV_WM_LEVEL_DDR_DVFS].plane[plane_id]); |
---|
| 1861 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 1862 | + "%s watermarks: PM2=%d, PM5=%d, DDR DVFS=%d\n", |
---|
| 1863 | + plane->base.name, |
---|
| 1864 | + crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2].plane[plane_id], |
---|
| 1865 | + crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM5].plane[plane_id], |
---|
| 1866 | + crtc_state->wm.vlv.raw[VLV_WM_LEVEL_DDR_DVFS].plane[plane_id]); |
---|
1816 | 1867 | |
---|
1817 | 1868 | return dirty; |
---|
1818 | 1869 | } |
---|
.. | .. |
---|
1838 | 1889 | |
---|
1839 | 1890 | static int vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state) |
---|
1840 | 1891 | { |
---|
1841 | | - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
---|
| 1892 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
1842 | 1893 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
1843 | 1894 | struct intel_atomic_state *state = |
---|
1844 | | - to_intel_atomic_state(crtc_state->base.state); |
---|
| 1895 | + to_intel_atomic_state(crtc_state->uapi.state); |
---|
1845 | 1896 | struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal; |
---|
1846 | 1897 | const struct vlv_fifo_state *fifo_state = |
---|
1847 | 1898 | &crtc_state->wm.vlv.fifo_state; |
---|
1848 | | - int num_active_planes = hweight32(crtc_state->active_planes & |
---|
1849 | | - ~BIT(PLANE_CURSOR)); |
---|
1850 | | - bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->base); |
---|
| 1899 | + int num_active_planes = hweight8(crtc_state->active_planes & |
---|
| 1900 | + ~BIT(PLANE_CURSOR)); |
---|
| 1901 | + bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->uapi); |
---|
1851 | 1902 | const struct intel_plane_state *old_plane_state; |
---|
1852 | 1903 | const struct intel_plane_state *new_plane_state; |
---|
1853 | 1904 | struct intel_plane *plane; |
---|
.. | .. |
---|
1858 | 1909 | for_each_oldnew_intel_plane_in_state(state, plane, |
---|
1859 | 1910 | old_plane_state, |
---|
1860 | 1911 | new_plane_state, i) { |
---|
1861 | | - if (new_plane_state->base.crtc != &crtc->base && |
---|
1862 | | - old_plane_state->base.crtc != &crtc->base) |
---|
| 1912 | + if (new_plane_state->hw.crtc != &crtc->base && |
---|
| 1913 | + old_plane_state->hw.crtc != &crtc->base) |
---|
1863 | 1914 | continue; |
---|
1864 | 1915 | |
---|
1865 | 1916 | if (vlv_raw_plane_wm_compute(crtc_state, new_plane_state)) |
---|
.. | .. |
---|
1906 | 1957 | |
---|
1907 | 1958 | for (level = 0; level < wm_state->num_levels; level++) { |
---|
1908 | 1959 | const struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[level]; |
---|
1909 | | - const int sr_fifo_size = INTEL_INFO(dev_priv)->num_pipes * 512 - 1; |
---|
| 1960 | + const int sr_fifo_size = INTEL_NUM_PIPES(dev_priv) * 512 - 1; |
---|
1910 | 1961 | |
---|
1911 | 1962 | if (!vlv_raw_crtc_wm_is_valid(crtc_state, level)) |
---|
1912 | 1963 | break; |
---|
.. | .. |
---|
1944 | 1995 | (((value) << DSPARB_ ## plane ## _SHIFT_VLV) & DSPARB_ ## plane ## _MASK_VLV) |
---|
1945 | 1996 | |
---|
1946 | 1997 | static void vlv_atomic_update_fifo(struct intel_atomic_state *state, |
---|
1947 | | - struct intel_crtc_state *crtc_state) |
---|
| 1998 | + struct intel_crtc *crtc) |
---|
1948 | 1999 | { |
---|
1949 | | - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
---|
1950 | 2000 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 2001 | + struct intel_uncore *uncore = &dev_priv->uncore; |
---|
| 2002 | + const struct intel_crtc_state *crtc_state = |
---|
| 2003 | + intel_atomic_get_new_crtc_state(state, crtc); |
---|
1951 | 2004 | const struct vlv_fifo_state *fifo_state = |
---|
1952 | 2005 | &crtc_state->wm.vlv.fifo_state; |
---|
1953 | 2006 | int sprite0_start, sprite1_start, fifo_size; |
---|
| 2007 | + u32 dsparb, dsparb2, dsparb3; |
---|
1954 | 2008 | |
---|
1955 | 2009 | if (!crtc_state->fifo_changed) |
---|
1956 | 2010 | return; |
---|
.. | .. |
---|
1959 | 2013 | sprite1_start = fifo_state->plane[PLANE_SPRITE0] + sprite0_start; |
---|
1960 | 2014 | fifo_size = fifo_state->plane[PLANE_SPRITE1] + sprite1_start; |
---|
1961 | 2015 | |
---|
1962 | | - WARN_ON(fifo_state->plane[PLANE_CURSOR] != 63); |
---|
1963 | | - WARN_ON(fifo_size != 511); |
---|
| 2016 | + drm_WARN_ON(&dev_priv->drm, fifo_state->plane[PLANE_CURSOR] != 63); |
---|
| 2017 | + drm_WARN_ON(&dev_priv->drm, fifo_size != 511); |
---|
1964 | 2018 | |
---|
1965 | 2019 | trace_vlv_fifo_size(crtc, sprite0_start, sprite1_start, fifo_size); |
---|
1966 | 2020 | |
---|
.. | .. |
---|
1973 | 2027 | * intel_pipe_update_start() has already disabled interrupts |
---|
1974 | 2028 | * for us, so a plain spin_lock() is sufficient here. |
---|
1975 | 2029 | */ |
---|
1976 | | - spin_lock(&dev_priv->uncore.lock); |
---|
| 2030 | + spin_lock(&uncore->lock); |
---|
1977 | 2031 | |
---|
1978 | 2032 | switch (crtc->pipe) { |
---|
1979 | | - uint32_t dsparb, dsparb2, dsparb3; |
---|
1980 | 2033 | case PIPE_A: |
---|
1981 | | - dsparb = I915_READ_FW(DSPARB); |
---|
1982 | | - dsparb2 = I915_READ_FW(DSPARB2); |
---|
| 2034 | + dsparb = intel_uncore_read_fw(uncore, DSPARB); |
---|
| 2035 | + dsparb2 = intel_uncore_read_fw(uncore, DSPARB2); |
---|
1983 | 2036 | |
---|
1984 | 2037 | dsparb &= ~(VLV_FIFO(SPRITEA, 0xff) | |
---|
1985 | 2038 | VLV_FIFO(SPRITEB, 0xff)); |
---|
.. | .. |
---|
1991 | 2044 | dsparb2 |= (VLV_FIFO(SPRITEA_HI, sprite0_start >> 8) | |
---|
1992 | 2045 | VLV_FIFO(SPRITEB_HI, sprite1_start >> 8)); |
---|
1993 | 2046 | |
---|
1994 | | - I915_WRITE_FW(DSPARB, dsparb); |
---|
1995 | | - I915_WRITE_FW(DSPARB2, dsparb2); |
---|
| 2047 | + intel_uncore_write_fw(uncore, DSPARB, dsparb); |
---|
| 2048 | + intel_uncore_write_fw(uncore, DSPARB2, dsparb2); |
---|
1996 | 2049 | break; |
---|
1997 | 2050 | case PIPE_B: |
---|
1998 | | - dsparb = I915_READ_FW(DSPARB); |
---|
1999 | | - dsparb2 = I915_READ_FW(DSPARB2); |
---|
| 2051 | + dsparb = intel_uncore_read_fw(uncore, DSPARB); |
---|
| 2052 | + dsparb2 = intel_uncore_read_fw(uncore, DSPARB2); |
---|
2000 | 2053 | |
---|
2001 | 2054 | dsparb &= ~(VLV_FIFO(SPRITEC, 0xff) | |
---|
2002 | 2055 | VLV_FIFO(SPRITED, 0xff)); |
---|
.. | .. |
---|
2008 | 2061 | dsparb2 |= (VLV_FIFO(SPRITEC_HI, sprite0_start >> 8) | |
---|
2009 | 2062 | VLV_FIFO(SPRITED_HI, sprite1_start >> 8)); |
---|
2010 | 2063 | |
---|
2011 | | - I915_WRITE_FW(DSPARB, dsparb); |
---|
2012 | | - I915_WRITE_FW(DSPARB2, dsparb2); |
---|
| 2064 | + intel_uncore_write_fw(uncore, DSPARB, dsparb); |
---|
| 2065 | + intel_uncore_write_fw(uncore, DSPARB2, dsparb2); |
---|
2013 | 2066 | break; |
---|
2014 | 2067 | case PIPE_C: |
---|
2015 | | - dsparb3 = I915_READ_FW(DSPARB3); |
---|
2016 | | - dsparb2 = I915_READ_FW(DSPARB2); |
---|
| 2068 | + dsparb3 = intel_uncore_read_fw(uncore, DSPARB3); |
---|
| 2069 | + dsparb2 = intel_uncore_read_fw(uncore, DSPARB2); |
---|
2017 | 2070 | |
---|
2018 | 2071 | dsparb3 &= ~(VLV_FIFO(SPRITEE, 0xff) | |
---|
2019 | 2072 | VLV_FIFO(SPRITEF, 0xff)); |
---|
.. | .. |
---|
2025 | 2078 | dsparb2 |= (VLV_FIFO(SPRITEE_HI, sprite0_start >> 8) | |
---|
2026 | 2079 | VLV_FIFO(SPRITEF_HI, sprite1_start >> 8)); |
---|
2027 | 2080 | |
---|
2028 | | - I915_WRITE_FW(DSPARB3, dsparb3); |
---|
2029 | | - I915_WRITE_FW(DSPARB2, dsparb2); |
---|
| 2081 | + intel_uncore_write_fw(uncore, DSPARB3, dsparb3); |
---|
| 2082 | + intel_uncore_write_fw(uncore, DSPARB2, dsparb2); |
---|
2030 | 2083 | break; |
---|
2031 | 2084 | default: |
---|
2032 | 2085 | break; |
---|
2033 | 2086 | } |
---|
2034 | 2087 | |
---|
2035 | | - POSTING_READ_FW(DSPARB); |
---|
| 2088 | + intel_uncore_posting_read_fw(uncore, DSPARB); |
---|
2036 | 2089 | |
---|
2037 | | - spin_unlock(&dev_priv->uncore.lock); |
---|
| 2090 | + spin_unlock(&uncore->lock); |
---|
2038 | 2091 | } |
---|
2039 | 2092 | |
---|
2040 | 2093 | #undef VLV_FIFO |
---|
2041 | 2094 | |
---|
2042 | | -static int vlv_compute_intermediate_wm(struct drm_device *dev, |
---|
2043 | | - struct intel_crtc *crtc, |
---|
2044 | | - struct intel_crtc_state *new_crtc_state) |
---|
| 2095 | +static int vlv_compute_intermediate_wm(struct intel_crtc_state *new_crtc_state) |
---|
2045 | 2096 | { |
---|
| 2097 | + struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); |
---|
2046 | 2098 | struct vlv_wm_state *intermediate = &new_crtc_state->wm.vlv.intermediate; |
---|
2047 | 2099 | const struct vlv_wm_state *optimal = &new_crtc_state->wm.vlv.optimal; |
---|
2048 | 2100 | struct intel_atomic_state *intel_state = |
---|
2049 | | - to_intel_atomic_state(new_crtc_state->base.state); |
---|
| 2101 | + to_intel_atomic_state(new_crtc_state->uapi.state); |
---|
2050 | 2102 | const struct intel_crtc_state *old_crtc_state = |
---|
2051 | 2103 | intel_atomic_get_old_crtc_state(intel_state, crtc); |
---|
2052 | 2104 | const struct vlv_wm_state *active = &old_crtc_state->wm.vlv.optimal; |
---|
2053 | 2105 | int level; |
---|
2054 | 2106 | |
---|
2055 | | - if (!new_crtc_state->base.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->base)) { |
---|
| 2107 | + if (!new_crtc_state->hw.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi)) { |
---|
2056 | 2108 | *intermediate = *optimal; |
---|
2057 | 2109 | |
---|
2058 | 2110 | intermediate->cxsr = false; |
---|
.. | .. |
---|
2095 | 2147 | struct vlv_wm_values *wm) |
---|
2096 | 2148 | { |
---|
2097 | 2149 | struct intel_crtc *crtc; |
---|
2098 | | - int num_active_crtcs = 0; |
---|
| 2150 | + int num_active_pipes = 0; |
---|
2099 | 2151 | |
---|
2100 | 2152 | wm->level = dev_priv->wm.max_level; |
---|
2101 | 2153 | wm->cxsr = true; |
---|
.. | .. |
---|
2109 | 2161 | if (!wm_state->cxsr) |
---|
2110 | 2162 | wm->cxsr = false; |
---|
2111 | 2163 | |
---|
2112 | | - num_active_crtcs++; |
---|
| 2164 | + num_active_pipes++; |
---|
2113 | 2165 | wm->level = min_t(int, wm->level, wm_state->num_levels - 1); |
---|
2114 | 2166 | } |
---|
2115 | 2167 | |
---|
2116 | | - if (num_active_crtcs != 1) |
---|
| 2168 | + if (num_active_pipes != 1) |
---|
2117 | 2169 | wm->cxsr = false; |
---|
2118 | 2170 | |
---|
2119 | | - if (num_active_crtcs > 1) |
---|
| 2171 | + if (num_active_pipes > 1) |
---|
2120 | 2172 | wm->level = VLV_WM_LEVEL_PM2; |
---|
2121 | 2173 | |
---|
2122 | 2174 | for_each_intel_crtc(&dev_priv->drm, crtc) { |
---|
.. | .. |
---|
2168 | 2220 | } |
---|
2169 | 2221 | |
---|
2170 | 2222 | static void vlv_initial_watermarks(struct intel_atomic_state *state, |
---|
2171 | | - struct intel_crtc_state *crtc_state) |
---|
| 2223 | + struct intel_crtc *crtc) |
---|
2172 | 2224 | { |
---|
2173 | | - struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); |
---|
2174 | | - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); |
---|
| 2225 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 2226 | + const struct intel_crtc_state *crtc_state = |
---|
| 2227 | + intel_atomic_get_new_crtc_state(state, crtc); |
---|
2175 | 2228 | |
---|
2176 | 2229 | mutex_lock(&dev_priv->wm.wm_mutex); |
---|
2177 | 2230 | crtc->wm.active.vlv = crtc_state->wm.vlv.intermediate; |
---|
.. | .. |
---|
2180 | 2233 | } |
---|
2181 | 2234 | |
---|
2182 | 2235 | static void vlv_optimize_watermarks(struct intel_atomic_state *state, |
---|
2183 | | - struct intel_crtc_state *crtc_state) |
---|
| 2236 | + struct intel_crtc *crtc) |
---|
2184 | 2237 | { |
---|
2185 | | - struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); |
---|
2186 | | - struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); |
---|
| 2238 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 2239 | + const struct intel_crtc_state *crtc_state = |
---|
| 2240 | + intel_atomic_get_new_crtc_state(state, crtc); |
---|
2187 | 2241 | |
---|
2188 | 2242 | if (!crtc_state->wm.need_postvbl_update) |
---|
2189 | 2243 | return; |
---|
2190 | 2244 | |
---|
2191 | 2245 | mutex_lock(&dev_priv->wm.wm_mutex); |
---|
2192 | | - intel_crtc->wm.active.vlv = crtc_state->wm.vlv.optimal; |
---|
| 2246 | + crtc->wm.active.vlv = crtc_state->wm.vlv.optimal; |
---|
2193 | 2247 | vlv_program_watermarks(dev_priv); |
---|
2194 | 2248 | mutex_unlock(&dev_priv->wm.wm_mutex); |
---|
2195 | 2249 | } |
---|
.. | .. |
---|
2208 | 2262 | /* self-refresh has much higher latency */ |
---|
2209 | 2263 | static const int sr_latency_ns = 12000; |
---|
2210 | 2264 | const struct drm_display_mode *adjusted_mode = |
---|
2211 | | - &crtc->config->base.adjusted_mode; |
---|
| 2265 | + &crtc->config->hw.adjusted_mode; |
---|
2212 | 2266 | const struct drm_framebuffer *fb = |
---|
2213 | 2267 | crtc->base.primary->state->fb; |
---|
2214 | 2268 | int clock = adjusted_mode->crtc_clock; |
---|
.. | .. |
---|
2224 | 2278 | if (srwm < 0) |
---|
2225 | 2279 | srwm = 1; |
---|
2226 | 2280 | srwm &= 0x1ff; |
---|
2227 | | - DRM_DEBUG_KMS("self-refresh entries: %d, wm: %d\n", |
---|
2228 | | - entries, srwm); |
---|
| 2281 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 2282 | + "self-refresh entries: %d, wm: %d\n", |
---|
| 2283 | + entries, srwm); |
---|
2229 | 2284 | |
---|
2230 | 2285 | entries = intel_wm_method2(clock, htotal, |
---|
2231 | 2286 | crtc->base.cursor->state->crtc_w, 4, |
---|
.. | .. |
---|
2238 | 2293 | if (cursor_sr > i965_cursor_wm_info.max_wm) |
---|
2239 | 2294 | cursor_sr = i965_cursor_wm_info.max_wm; |
---|
2240 | 2295 | |
---|
2241 | | - DRM_DEBUG_KMS("self-refresh watermark: display plane %d " |
---|
2242 | | - "cursor %d\n", srwm, cursor_sr); |
---|
| 2296 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 2297 | + "self-refresh watermark: display plane %d " |
---|
| 2298 | + "cursor %d\n", srwm, cursor_sr); |
---|
2243 | 2299 | |
---|
2244 | 2300 | cxsr_enabled = true; |
---|
2245 | 2301 | } else { |
---|
.. | .. |
---|
2248 | 2304 | intel_set_memory_cxsr(dev_priv, false); |
---|
2249 | 2305 | } |
---|
2250 | 2306 | |
---|
2251 | | - DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", |
---|
2252 | | - srwm); |
---|
| 2307 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 2308 | + "Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", |
---|
| 2309 | + srwm); |
---|
2253 | 2310 | |
---|
2254 | 2311 | /* 965 has limitations... */ |
---|
2255 | 2312 | I915_WRITE(DSPFW1, FW_WM(srwm, SR) | |
---|
.. | .. |
---|
2271 | 2328 | { |
---|
2272 | 2329 | struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev); |
---|
2273 | 2330 | const struct intel_watermark_params *wm_info; |
---|
2274 | | - uint32_t fwater_lo; |
---|
2275 | | - uint32_t fwater_hi; |
---|
| 2331 | + u32 fwater_lo; |
---|
| 2332 | + u32 fwater_hi; |
---|
2276 | 2333 | int cwm, srwm = 1; |
---|
2277 | 2334 | int fifo_size; |
---|
2278 | 2335 | int planea_wm, planeb_wm; |
---|
.. | .. |
---|
2280 | 2337 | |
---|
2281 | 2338 | if (IS_I945GM(dev_priv)) |
---|
2282 | 2339 | wm_info = &i945_wm_info; |
---|
2283 | | - else if (!IS_GEN2(dev_priv)) |
---|
| 2340 | + else if (!IS_GEN(dev_priv, 2)) |
---|
2284 | 2341 | wm_info = &i915_wm_info; |
---|
2285 | 2342 | else |
---|
2286 | 2343 | wm_info = &i830_a_wm_info; |
---|
.. | .. |
---|
2289 | 2346 | crtc = intel_get_crtc_for_plane(dev_priv, PLANE_A); |
---|
2290 | 2347 | if (intel_crtc_active(crtc)) { |
---|
2291 | 2348 | const struct drm_display_mode *adjusted_mode = |
---|
2292 | | - &crtc->config->base.adjusted_mode; |
---|
| 2349 | + &crtc->config->hw.adjusted_mode; |
---|
2293 | 2350 | const struct drm_framebuffer *fb = |
---|
2294 | 2351 | crtc->base.primary->state->fb; |
---|
2295 | 2352 | int cpp; |
---|
2296 | 2353 | |
---|
2297 | | - if (IS_GEN2(dev_priv)) |
---|
| 2354 | + if (IS_GEN(dev_priv, 2)) |
---|
2298 | 2355 | cpp = 4; |
---|
2299 | 2356 | else |
---|
2300 | 2357 | cpp = fb->format->cpp[0]; |
---|
.. | .. |
---|
2309 | 2366 | planea_wm = wm_info->max_wm; |
---|
2310 | 2367 | } |
---|
2311 | 2368 | |
---|
2312 | | - if (IS_GEN2(dev_priv)) |
---|
| 2369 | + if (IS_GEN(dev_priv, 2)) |
---|
2313 | 2370 | wm_info = &i830_bc_wm_info; |
---|
2314 | 2371 | |
---|
2315 | 2372 | fifo_size = dev_priv->display.get_fifo_size(dev_priv, PLANE_B); |
---|
2316 | 2373 | crtc = intel_get_crtc_for_plane(dev_priv, PLANE_B); |
---|
2317 | 2374 | if (intel_crtc_active(crtc)) { |
---|
2318 | 2375 | const struct drm_display_mode *adjusted_mode = |
---|
2319 | | - &crtc->config->base.adjusted_mode; |
---|
| 2376 | + &crtc->config->hw.adjusted_mode; |
---|
2320 | 2377 | const struct drm_framebuffer *fb = |
---|
2321 | 2378 | crtc->base.primary->state->fb; |
---|
2322 | 2379 | int cpp; |
---|
2323 | 2380 | |
---|
2324 | | - if (IS_GEN2(dev_priv)) |
---|
| 2381 | + if (IS_GEN(dev_priv, 2)) |
---|
2325 | 2382 | cpp = 4; |
---|
2326 | 2383 | else |
---|
2327 | 2384 | cpp = fb->format->cpp[0]; |
---|
.. | .. |
---|
2339 | 2396 | planeb_wm = wm_info->max_wm; |
---|
2340 | 2397 | } |
---|
2341 | 2398 | |
---|
2342 | | - DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); |
---|
| 2399 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 2400 | + "FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); |
---|
2343 | 2401 | |
---|
2344 | 2402 | if (IS_I915GM(dev_priv) && enabled) { |
---|
2345 | 2403 | struct drm_i915_gem_object *obj; |
---|
.. | .. |
---|
2364 | 2422 | /* self-refresh has much higher latency */ |
---|
2365 | 2423 | static const int sr_latency_ns = 6000; |
---|
2366 | 2424 | const struct drm_display_mode *adjusted_mode = |
---|
2367 | | - &enabled->config->base.adjusted_mode; |
---|
| 2425 | + &enabled->config->hw.adjusted_mode; |
---|
2368 | 2426 | const struct drm_framebuffer *fb = |
---|
2369 | 2427 | enabled->base.primary->state->fb; |
---|
2370 | 2428 | int clock = adjusted_mode->crtc_clock; |
---|
.. | .. |
---|
2381 | 2439 | entries = intel_wm_method2(clock, htotal, hdisplay, cpp, |
---|
2382 | 2440 | sr_latency_ns / 100); |
---|
2383 | 2441 | entries = DIV_ROUND_UP(entries, wm_info->cacheline_size); |
---|
2384 | | - DRM_DEBUG_KMS("self-refresh entries: %d\n", entries); |
---|
| 2442 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 2443 | + "self-refresh entries: %d\n", entries); |
---|
2385 | 2444 | srwm = wm_info->fifo_size - entries; |
---|
2386 | 2445 | if (srwm < 0) |
---|
2387 | 2446 | srwm = 1; |
---|
.. | .. |
---|
2393 | 2452 | I915_WRITE(FW_BLC_SELF, srwm & 0x3f); |
---|
2394 | 2453 | } |
---|
2395 | 2454 | |
---|
2396 | | - DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", |
---|
2397 | | - planea_wm, planeb_wm, cwm, srwm); |
---|
| 2455 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 2456 | + "Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", |
---|
| 2457 | + planea_wm, planeb_wm, cwm, srwm); |
---|
2398 | 2458 | |
---|
2399 | 2459 | fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f); |
---|
2400 | 2460 | fwater_hi = (cwm & 0x1f); |
---|
.. | .. |
---|
2415 | 2475 | struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev); |
---|
2416 | 2476 | struct intel_crtc *crtc; |
---|
2417 | 2477 | const struct drm_display_mode *adjusted_mode; |
---|
2418 | | - uint32_t fwater_lo; |
---|
| 2478 | + u32 fwater_lo; |
---|
2419 | 2479 | int planea_wm; |
---|
2420 | 2480 | |
---|
2421 | 2481 | crtc = single_enabled_crtc(dev_priv); |
---|
2422 | 2482 | if (crtc == NULL) |
---|
2423 | 2483 | return; |
---|
2424 | 2484 | |
---|
2425 | | - adjusted_mode = &crtc->config->base.adjusted_mode; |
---|
| 2485 | + adjusted_mode = &crtc->config->hw.adjusted_mode; |
---|
2426 | 2486 | planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock, |
---|
2427 | 2487 | &i845_wm_info, |
---|
2428 | 2488 | dev_priv->display.get_fifo_size(dev_priv, PLANE_A), |
---|
.. | .. |
---|
2430 | 2490 | fwater_lo = I915_READ(FW_BLC) & ~0xfff; |
---|
2431 | 2491 | fwater_lo |= (3<<8) | planea_wm; |
---|
2432 | 2492 | |
---|
2433 | | - DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm); |
---|
| 2493 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 2494 | + "Setting FIFO watermarks - A: %d\n", planea_wm); |
---|
2434 | 2495 | |
---|
2435 | 2496 | I915_WRITE(FW_BLC, fwater_lo); |
---|
2436 | 2497 | } |
---|
.. | .. |
---|
2464 | 2525 | return ret; |
---|
2465 | 2526 | } |
---|
2466 | 2527 | |
---|
2467 | | -static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels, |
---|
2468 | | - uint8_t cpp) |
---|
| 2528 | +static u32 ilk_wm_fbc(u32 pri_val, u32 horiz_pixels, u8 cpp) |
---|
2469 | 2529 | { |
---|
2470 | 2530 | /* |
---|
2471 | 2531 | * Neither of these should be possible since this function shouldn't be |
---|
.. | .. |
---|
2482 | 2542 | } |
---|
2483 | 2543 | |
---|
2484 | 2544 | struct ilk_wm_maximums { |
---|
2485 | | - uint16_t pri; |
---|
2486 | | - uint16_t spr; |
---|
2487 | | - uint16_t cur; |
---|
2488 | | - uint16_t fbc; |
---|
| 2545 | + u16 pri; |
---|
| 2546 | + u16 spr; |
---|
| 2547 | + u16 cur; |
---|
| 2548 | + u16 fbc; |
---|
2489 | 2549 | }; |
---|
2490 | 2550 | |
---|
2491 | 2551 | /* |
---|
2492 | 2552 | * For both WM_PIPE and WM_LP. |
---|
2493 | 2553 | * mem_value must be in 0.1us units. |
---|
2494 | 2554 | */ |
---|
2495 | | -static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate, |
---|
2496 | | - const struct intel_plane_state *pstate, |
---|
2497 | | - uint32_t mem_value, |
---|
2498 | | - bool is_lp) |
---|
| 2555 | +static u32 ilk_compute_pri_wm(const struct intel_crtc_state *crtc_state, |
---|
| 2556 | + const struct intel_plane_state *plane_state, |
---|
| 2557 | + u32 mem_value, bool is_lp) |
---|
2499 | 2558 | { |
---|
2500 | | - uint32_t method1, method2; |
---|
| 2559 | + u32 method1, method2; |
---|
2501 | 2560 | int cpp; |
---|
2502 | 2561 | |
---|
2503 | 2562 | if (mem_value == 0) |
---|
2504 | 2563 | return U32_MAX; |
---|
2505 | 2564 | |
---|
2506 | | - if (!intel_wm_plane_visible(cstate, pstate)) |
---|
| 2565 | + if (!intel_wm_plane_visible(crtc_state, plane_state)) |
---|
2507 | 2566 | return 0; |
---|
2508 | 2567 | |
---|
2509 | | - cpp = pstate->base.fb->format->cpp[0]; |
---|
| 2568 | + cpp = plane_state->hw.fb->format->cpp[0]; |
---|
2510 | 2569 | |
---|
2511 | | - method1 = ilk_wm_method1(cstate->pixel_rate, cpp, mem_value); |
---|
| 2570 | + method1 = ilk_wm_method1(crtc_state->pixel_rate, cpp, mem_value); |
---|
2512 | 2571 | |
---|
2513 | 2572 | if (!is_lp) |
---|
2514 | 2573 | return method1; |
---|
2515 | 2574 | |
---|
2516 | | - method2 = ilk_wm_method2(cstate->pixel_rate, |
---|
2517 | | - cstate->base.adjusted_mode.crtc_htotal, |
---|
2518 | | - drm_rect_width(&pstate->base.dst), |
---|
| 2575 | + method2 = ilk_wm_method2(crtc_state->pixel_rate, |
---|
| 2576 | + crtc_state->hw.adjusted_mode.crtc_htotal, |
---|
| 2577 | + drm_rect_width(&plane_state->uapi.dst), |
---|
2519 | 2578 | cpp, mem_value); |
---|
2520 | 2579 | |
---|
2521 | 2580 | return min(method1, method2); |
---|
.. | .. |
---|
2525 | 2584 | * For both WM_PIPE and WM_LP. |
---|
2526 | 2585 | * mem_value must be in 0.1us units. |
---|
2527 | 2586 | */ |
---|
2528 | | -static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate, |
---|
2529 | | - const struct intel_plane_state *pstate, |
---|
2530 | | - uint32_t mem_value) |
---|
| 2587 | +static u32 ilk_compute_spr_wm(const struct intel_crtc_state *crtc_state, |
---|
| 2588 | + const struct intel_plane_state *plane_state, |
---|
| 2589 | + u32 mem_value) |
---|
2531 | 2590 | { |
---|
2532 | | - uint32_t method1, method2; |
---|
| 2591 | + u32 method1, method2; |
---|
2533 | 2592 | int cpp; |
---|
2534 | 2593 | |
---|
2535 | 2594 | if (mem_value == 0) |
---|
2536 | 2595 | return U32_MAX; |
---|
2537 | 2596 | |
---|
2538 | | - if (!intel_wm_plane_visible(cstate, pstate)) |
---|
| 2597 | + if (!intel_wm_plane_visible(crtc_state, plane_state)) |
---|
2539 | 2598 | return 0; |
---|
2540 | 2599 | |
---|
2541 | | - cpp = pstate->base.fb->format->cpp[0]; |
---|
| 2600 | + cpp = plane_state->hw.fb->format->cpp[0]; |
---|
2542 | 2601 | |
---|
2543 | | - method1 = ilk_wm_method1(cstate->pixel_rate, cpp, mem_value); |
---|
2544 | | - method2 = ilk_wm_method2(cstate->pixel_rate, |
---|
2545 | | - cstate->base.adjusted_mode.crtc_htotal, |
---|
2546 | | - drm_rect_width(&pstate->base.dst), |
---|
| 2602 | + method1 = ilk_wm_method1(crtc_state->pixel_rate, cpp, mem_value); |
---|
| 2603 | + method2 = ilk_wm_method2(crtc_state->pixel_rate, |
---|
| 2604 | + crtc_state->hw.adjusted_mode.crtc_htotal, |
---|
| 2605 | + drm_rect_width(&plane_state->uapi.dst), |
---|
2547 | 2606 | cpp, mem_value); |
---|
2548 | 2607 | return min(method1, method2); |
---|
2549 | 2608 | } |
---|
.. | .. |
---|
2552 | 2611 | * For both WM_PIPE and WM_LP. |
---|
2553 | 2612 | * mem_value must be in 0.1us units. |
---|
2554 | 2613 | */ |
---|
2555 | | -static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate, |
---|
2556 | | - const struct intel_plane_state *pstate, |
---|
2557 | | - uint32_t mem_value) |
---|
| 2614 | +static u32 ilk_compute_cur_wm(const struct intel_crtc_state *crtc_state, |
---|
| 2615 | + const struct intel_plane_state *plane_state, |
---|
| 2616 | + u32 mem_value) |
---|
2558 | 2617 | { |
---|
2559 | 2618 | int cpp; |
---|
2560 | 2619 | |
---|
2561 | 2620 | if (mem_value == 0) |
---|
2562 | 2621 | return U32_MAX; |
---|
2563 | 2622 | |
---|
2564 | | - if (!intel_wm_plane_visible(cstate, pstate)) |
---|
| 2623 | + if (!intel_wm_plane_visible(crtc_state, plane_state)) |
---|
2565 | 2624 | return 0; |
---|
2566 | 2625 | |
---|
2567 | | - cpp = pstate->base.fb->format->cpp[0]; |
---|
| 2626 | + cpp = plane_state->hw.fb->format->cpp[0]; |
---|
2568 | 2627 | |
---|
2569 | | - return ilk_wm_method2(cstate->pixel_rate, |
---|
2570 | | - cstate->base.adjusted_mode.crtc_htotal, |
---|
2571 | | - pstate->base.crtc_w, cpp, mem_value); |
---|
| 2628 | + return ilk_wm_method2(crtc_state->pixel_rate, |
---|
| 2629 | + crtc_state->hw.adjusted_mode.crtc_htotal, |
---|
| 2630 | + drm_rect_width(&plane_state->uapi.dst), |
---|
| 2631 | + cpp, mem_value); |
---|
2572 | 2632 | } |
---|
2573 | 2633 | |
---|
2574 | 2634 | /* Only for WM_LP. */ |
---|
2575 | | -static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate, |
---|
2576 | | - const struct intel_plane_state *pstate, |
---|
2577 | | - uint32_t pri_val) |
---|
| 2635 | +static u32 ilk_compute_fbc_wm(const struct intel_crtc_state *crtc_state, |
---|
| 2636 | + const struct intel_plane_state *plane_state, |
---|
| 2637 | + u32 pri_val) |
---|
2578 | 2638 | { |
---|
2579 | 2639 | int cpp; |
---|
2580 | 2640 | |
---|
2581 | | - if (!intel_wm_plane_visible(cstate, pstate)) |
---|
| 2641 | + if (!intel_wm_plane_visible(crtc_state, plane_state)) |
---|
2582 | 2642 | return 0; |
---|
2583 | 2643 | |
---|
2584 | | - cpp = pstate->base.fb->format->cpp[0]; |
---|
| 2644 | + cpp = plane_state->hw.fb->format->cpp[0]; |
---|
2585 | 2645 | |
---|
2586 | | - return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->base.dst), cpp); |
---|
| 2646 | + return ilk_wm_fbc(pri_val, drm_rect_width(&plane_state->uapi.dst), |
---|
| 2647 | + cpp); |
---|
2587 | 2648 | } |
---|
2588 | 2649 | |
---|
2589 | 2650 | static unsigned int |
---|
.. | .. |
---|
2633 | 2694 | } |
---|
2634 | 2695 | |
---|
2635 | 2696 | /* Calculate the maximum primary/sprite plane watermark */ |
---|
2636 | | -static unsigned int ilk_plane_wm_max(const struct drm_device *dev, |
---|
| 2697 | +static unsigned int ilk_plane_wm_max(const struct drm_i915_private *dev_priv, |
---|
2637 | 2698 | int level, |
---|
2638 | 2699 | const struct intel_wm_config *config, |
---|
2639 | 2700 | enum intel_ddb_partitioning ddb_partitioning, |
---|
2640 | 2701 | bool is_sprite) |
---|
2641 | 2702 | { |
---|
2642 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
2643 | 2703 | unsigned int fifo_size = ilk_display_fifo_size(dev_priv); |
---|
2644 | 2704 | |
---|
2645 | 2705 | /* if sprites aren't enabled, sprites get nothing */ |
---|
.. | .. |
---|
2648 | 2708 | |
---|
2649 | 2709 | /* HSW allows LP1+ watermarks even with multiple pipes */ |
---|
2650 | 2710 | if (level == 0 || config->num_pipes_active > 1) { |
---|
2651 | | - fifo_size /= INTEL_INFO(dev_priv)->num_pipes; |
---|
| 2711 | + fifo_size /= INTEL_NUM_PIPES(dev_priv); |
---|
2652 | 2712 | |
---|
2653 | 2713 | /* |
---|
2654 | 2714 | * For some reason the non self refresh |
---|
.. | .. |
---|
2675 | 2735 | } |
---|
2676 | 2736 | |
---|
2677 | 2737 | /* Calculate the maximum cursor plane watermark */ |
---|
2678 | | -static unsigned int ilk_cursor_wm_max(const struct drm_device *dev, |
---|
| 2738 | +static unsigned int ilk_cursor_wm_max(const struct drm_i915_private *dev_priv, |
---|
2679 | 2739 | int level, |
---|
2680 | 2740 | const struct intel_wm_config *config) |
---|
2681 | 2741 | { |
---|
.. | .. |
---|
2684 | 2744 | return 64; |
---|
2685 | 2745 | |
---|
2686 | 2746 | /* otherwise just report max that registers can hold */ |
---|
2687 | | - return ilk_cursor_wm_reg_max(to_i915(dev), level); |
---|
| 2747 | + return ilk_cursor_wm_reg_max(dev_priv, level); |
---|
2688 | 2748 | } |
---|
2689 | 2749 | |
---|
2690 | | -static void ilk_compute_wm_maximums(const struct drm_device *dev, |
---|
| 2750 | +static void ilk_compute_wm_maximums(const struct drm_i915_private *dev_priv, |
---|
2691 | 2751 | int level, |
---|
2692 | 2752 | const struct intel_wm_config *config, |
---|
2693 | 2753 | enum intel_ddb_partitioning ddb_partitioning, |
---|
2694 | 2754 | struct ilk_wm_maximums *max) |
---|
2695 | 2755 | { |
---|
2696 | | - max->pri = ilk_plane_wm_max(dev, level, config, ddb_partitioning, false); |
---|
2697 | | - max->spr = ilk_plane_wm_max(dev, level, config, ddb_partitioning, true); |
---|
2698 | | - max->cur = ilk_cursor_wm_max(dev, level, config); |
---|
2699 | | - max->fbc = ilk_fbc_wm_reg_max(to_i915(dev)); |
---|
| 2756 | + max->pri = ilk_plane_wm_max(dev_priv, level, config, ddb_partitioning, false); |
---|
| 2757 | + max->spr = ilk_plane_wm_max(dev_priv, level, config, ddb_partitioning, true); |
---|
| 2758 | + max->cur = ilk_cursor_wm_max(dev_priv, level, config); |
---|
| 2759 | + max->fbc = ilk_fbc_wm_reg_max(dev_priv); |
---|
2700 | 2760 | } |
---|
2701 | 2761 | |
---|
2702 | 2762 | static void ilk_compute_wm_reg_maximums(const struct drm_i915_private *dev_priv, |
---|
.. | .. |
---|
2741 | 2801 | DRM_DEBUG_KMS("Cursor WM%d too large %u (max %u)\n", |
---|
2742 | 2802 | level, result->cur_val, max->cur); |
---|
2743 | 2803 | |
---|
2744 | | - result->pri_val = min_t(uint32_t, result->pri_val, max->pri); |
---|
2745 | | - result->spr_val = min_t(uint32_t, result->spr_val, max->spr); |
---|
2746 | | - result->cur_val = min_t(uint32_t, result->cur_val, max->cur); |
---|
| 2804 | + result->pri_val = min_t(u32, result->pri_val, max->pri); |
---|
| 2805 | + result->spr_val = min_t(u32, result->spr_val, max->spr); |
---|
| 2806 | + result->cur_val = min_t(u32, result->cur_val, max->cur); |
---|
2747 | 2807 | result->enable = true; |
---|
2748 | 2808 | } |
---|
2749 | 2809 | |
---|
.. | .. |
---|
2751 | 2811 | } |
---|
2752 | 2812 | |
---|
2753 | 2813 | static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, |
---|
2754 | | - const struct intel_crtc *intel_crtc, |
---|
| 2814 | + const struct intel_crtc *crtc, |
---|
2755 | 2815 | int level, |
---|
2756 | | - struct intel_crtc_state *cstate, |
---|
| 2816 | + struct intel_crtc_state *crtc_state, |
---|
2757 | 2817 | const struct intel_plane_state *pristate, |
---|
2758 | 2818 | const struct intel_plane_state *sprstate, |
---|
2759 | 2819 | const struct intel_plane_state *curstate, |
---|
2760 | 2820 | struct intel_wm_level *result) |
---|
2761 | 2821 | { |
---|
2762 | | - uint16_t pri_latency = dev_priv->wm.pri_latency[level]; |
---|
2763 | | - uint16_t spr_latency = dev_priv->wm.spr_latency[level]; |
---|
2764 | | - uint16_t cur_latency = dev_priv->wm.cur_latency[level]; |
---|
| 2822 | + u16 pri_latency = dev_priv->wm.pri_latency[level]; |
---|
| 2823 | + u16 spr_latency = dev_priv->wm.spr_latency[level]; |
---|
| 2824 | + u16 cur_latency = dev_priv->wm.cur_latency[level]; |
---|
2765 | 2825 | |
---|
2766 | 2826 | /* WM1+ latency values stored in 0.5us units */ |
---|
2767 | 2827 | if (level > 0) { |
---|
.. | .. |
---|
2771 | 2831 | } |
---|
2772 | 2832 | |
---|
2773 | 2833 | if (pristate) { |
---|
2774 | | - result->pri_val = ilk_compute_pri_wm(cstate, pristate, |
---|
| 2834 | + result->pri_val = ilk_compute_pri_wm(crtc_state, pristate, |
---|
2775 | 2835 | pri_latency, level); |
---|
2776 | | - result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val); |
---|
| 2836 | + result->fbc_val = ilk_compute_fbc_wm(crtc_state, pristate, result->pri_val); |
---|
2777 | 2837 | } |
---|
2778 | 2838 | |
---|
2779 | 2839 | if (sprstate) |
---|
2780 | | - result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency); |
---|
| 2840 | + result->spr_val = ilk_compute_spr_wm(crtc_state, sprstate, spr_latency); |
---|
2781 | 2841 | |
---|
2782 | 2842 | if (curstate) |
---|
2783 | | - result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency); |
---|
| 2843 | + result->cur_val = ilk_compute_cur_wm(crtc_state, curstate, cur_latency); |
---|
2784 | 2844 | |
---|
2785 | 2845 | result->enable = true; |
---|
2786 | 2846 | } |
---|
2787 | 2847 | |
---|
2788 | | -static uint32_t |
---|
2789 | | -hsw_compute_linetime_wm(const struct intel_crtc_state *cstate) |
---|
2790 | | -{ |
---|
2791 | | - const struct intel_atomic_state *intel_state = |
---|
2792 | | - to_intel_atomic_state(cstate->base.state); |
---|
2793 | | - const struct drm_display_mode *adjusted_mode = |
---|
2794 | | - &cstate->base.adjusted_mode; |
---|
2795 | | - u32 linetime, ips_linetime; |
---|
2796 | | - |
---|
2797 | | - if (!cstate->base.active) |
---|
2798 | | - return 0; |
---|
2799 | | - if (WARN_ON(adjusted_mode->crtc_clock == 0)) |
---|
2800 | | - return 0; |
---|
2801 | | - if (WARN_ON(intel_state->cdclk.logical.cdclk == 0)) |
---|
2802 | | - return 0; |
---|
2803 | | - |
---|
2804 | | - /* The WM are computed with base on how long it takes to fill a single |
---|
2805 | | - * row at the given clock rate, multiplied by 8. |
---|
2806 | | - * */ |
---|
2807 | | - linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8, |
---|
2808 | | - adjusted_mode->crtc_clock); |
---|
2809 | | - ips_linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8, |
---|
2810 | | - intel_state->cdclk.logical.cdclk); |
---|
2811 | | - |
---|
2812 | | - return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) | |
---|
2813 | | - PIPE_WM_LINETIME_TIME(linetime); |
---|
2814 | | -} |
---|
2815 | | - |
---|
2816 | 2848 | static void intel_read_wm_latency(struct drm_i915_private *dev_priv, |
---|
2817 | | - uint16_t wm[8]) |
---|
| 2849 | + u16 wm[]) |
---|
2818 | 2850 | { |
---|
| 2851 | + struct intel_uncore *uncore = &dev_priv->uncore; |
---|
| 2852 | + |
---|
2819 | 2853 | if (INTEL_GEN(dev_priv) >= 9) { |
---|
2820 | | - uint32_t val; |
---|
| 2854 | + u32 val; |
---|
2821 | 2855 | int ret, i; |
---|
2822 | 2856 | int level, max_level = ilk_wm_max_level(dev_priv); |
---|
2823 | 2857 | |
---|
2824 | 2858 | /* read the first set of memory latencies[0:3] */ |
---|
2825 | 2859 | val = 0; /* data0 to be programmed to 0 for first set */ |
---|
2826 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
2827 | 2860 | ret = sandybridge_pcode_read(dev_priv, |
---|
2828 | 2861 | GEN9_PCODE_READ_MEM_LATENCY, |
---|
2829 | | - &val); |
---|
2830 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
| 2862 | + &val, NULL); |
---|
2831 | 2863 | |
---|
2832 | 2864 | if (ret) { |
---|
2833 | | - DRM_ERROR("SKL Mailbox read error = %d\n", ret); |
---|
| 2865 | + drm_err(&dev_priv->drm, |
---|
| 2866 | + "SKL Mailbox read error = %d\n", ret); |
---|
2834 | 2867 | return; |
---|
2835 | 2868 | } |
---|
2836 | 2869 | |
---|
.. | .. |
---|
2844 | 2877 | |
---|
2845 | 2878 | /* read the second set of memory latencies[4:7] */ |
---|
2846 | 2879 | val = 1; /* data0 to be programmed to 1 for second set */ |
---|
2847 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
2848 | 2880 | ret = sandybridge_pcode_read(dev_priv, |
---|
2849 | 2881 | GEN9_PCODE_READ_MEM_LATENCY, |
---|
2850 | | - &val); |
---|
2851 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
| 2882 | + &val, NULL); |
---|
2852 | 2883 | if (ret) { |
---|
2853 | | - DRM_ERROR("SKL Mailbox read error = %d\n", ret); |
---|
| 2884 | + drm_err(&dev_priv->drm, |
---|
| 2885 | + "SKL Mailbox read error = %d\n", ret); |
---|
2854 | 2886 | return; |
---|
2855 | 2887 | } |
---|
2856 | 2888 | |
---|
.. | .. |
---|
2891 | 2923 | } |
---|
2892 | 2924 | } |
---|
2893 | 2925 | |
---|
| 2926 | + /* |
---|
| 2927 | + * WA Level-0 adjustment for 16GB DIMMs: SKL+ |
---|
| 2928 | + * If we could not get dimm info enable this WA to prevent from |
---|
| 2929 | + * any underrun. If not able to get Dimm info assume 16GB dimm |
---|
| 2930 | + * to avoid any underrun. |
---|
| 2931 | + */ |
---|
| 2932 | + if (dev_priv->dram_info.is_16gb_dimm) |
---|
| 2933 | + wm[0] += 1; |
---|
| 2934 | + |
---|
2894 | 2935 | } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { |
---|
2895 | | - uint64_t sskpd = I915_READ64(MCH_SSKPD); |
---|
| 2936 | + u64 sskpd = intel_uncore_read64(uncore, MCH_SSKPD); |
---|
2896 | 2937 | |
---|
2897 | 2938 | wm[0] = (sskpd >> 56) & 0xFF; |
---|
2898 | 2939 | if (wm[0] == 0) |
---|
.. | .. |
---|
2902 | 2943 | wm[3] = (sskpd >> 20) & 0x1FF; |
---|
2903 | 2944 | wm[4] = (sskpd >> 32) & 0x1FF; |
---|
2904 | 2945 | } else if (INTEL_GEN(dev_priv) >= 6) { |
---|
2905 | | - uint32_t sskpd = I915_READ(MCH_SSKPD); |
---|
| 2946 | + u32 sskpd = intel_uncore_read(uncore, MCH_SSKPD); |
---|
2906 | 2947 | |
---|
2907 | 2948 | wm[0] = (sskpd >> SSKPD_WM0_SHIFT) & SSKPD_WM_MASK; |
---|
2908 | 2949 | wm[1] = (sskpd >> SSKPD_WM1_SHIFT) & SSKPD_WM_MASK; |
---|
2909 | 2950 | wm[2] = (sskpd >> SSKPD_WM2_SHIFT) & SSKPD_WM_MASK; |
---|
2910 | 2951 | wm[3] = (sskpd >> SSKPD_WM3_SHIFT) & SSKPD_WM_MASK; |
---|
2911 | 2952 | } else if (INTEL_GEN(dev_priv) >= 5) { |
---|
2912 | | - uint32_t mltr = I915_READ(MLTR_ILK); |
---|
| 2953 | + u32 mltr = intel_uncore_read(uncore, MLTR_ILK); |
---|
2913 | 2954 | |
---|
2914 | 2955 | /* ILK primary LP0 latency is 700 ns */ |
---|
2915 | 2956 | wm[0] = 7; |
---|
.. | .. |
---|
2921 | 2962 | } |
---|
2922 | 2963 | |
---|
2923 | 2964 | static void intel_fixup_spr_wm_latency(struct drm_i915_private *dev_priv, |
---|
2924 | | - uint16_t wm[5]) |
---|
| 2965 | + u16 wm[5]) |
---|
2925 | 2966 | { |
---|
2926 | 2967 | /* ILK sprite LP0 latency is 1300 ns */ |
---|
2927 | | - if (IS_GEN5(dev_priv)) |
---|
| 2968 | + if (IS_GEN(dev_priv, 5)) |
---|
2928 | 2969 | wm[0] = 13; |
---|
2929 | 2970 | } |
---|
2930 | 2971 | |
---|
2931 | 2972 | static void intel_fixup_cur_wm_latency(struct drm_i915_private *dev_priv, |
---|
2932 | | - uint16_t wm[5]) |
---|
| 2973 | + u16 wm[5]) |
---|
2933 | 2974 | { |
---|
2934 | 2975 | /* ILK cursor LP0 latency is 1300 ns */ |
---|
2935 | | - if (IS_GEN5(dev_priv)) |
---|
| 2976 | + if (IS_GEN(dev_priv, 5)) |
---|
2936 | 2977 | wm[0] = 13; |
---|
2937 | 2978 | } |
---|
2938 | 2979 | |
---|
.. | .. |
---|
2951 | 2992 | |
---|
2952 | 2993 | static void intel_print_wm_latency(struct drm_i915_private *dev_priv, |
---|
2953 | 2994 | const char *name, |
---|
2954 | | - const uint16_t wm[]) |
---|
| 2995 | + const u16 wm[]) |
---|
2955 | 2996 | { |
---|
2956 | 2997 | int level, max_level = ilk_wm_max_level(dev_priv); |
---|
2957 | 2998 | |
---|
.. | .. |
---|
2959 | 3000 | unsigned int latency = wm[level]; |
---|
2960 | 3001 | |
---|
2961 | 3002 | if (latency == 0) { |
---|
2962 | | - DRM_DEBUG_KMS("%s WM%d latency not provided\n", |
---|
2963 | | - name, level); |
---|
| 3003 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 3004 | + "%s WM%d latency not provided\n", |
---|
| 3005 | + name, level); |
---|
2964 | 3006 | continue; |
---|
2965 | 3007 | } |
---|
2966 | 3008 | |
---|
.. | .. |
---|
2973 | 3015 | else if (level > 0) |
---|
2974 | 3016 | latency *= 5; |
---|
2975 | 3017 | |
---|
2976 | | - DRM_DEBUG_KMS("%s WM%d latency %u (%u.%u usec)\n", |
---|
2977 | | - name, level, wm[level], |
---|
2978 | | - latency / 10, latency % 10); |
---|
| 3018 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 3019 | + "%s WM%d latency %u (%u.%u usec)\n", name, level, |
---|
| 3020 | + wm[level], latency / 10, latency % 10); |
---|
2979 | 3021 | } |
---|
2980 | 3022 | } |
---|
2981 | 3023 | |
---|
2982 | 3024 | static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv, |
---|
2983 | | - uint16_t wm[5], uint16_t min) |
---|
| 3025 | + u16 wm[5], u16 min) |
---|
2984 | 3026 | { |
---|
2985 | 3027 | int level, max_level = ilk_wm_max_level(dev_priv); |
---|
2986 | 3028 | |
---|
.. | .. |
---|
2989 | 3031 | |
---|
2990 | 3032 | wm[0] = max(wm[0], min); |
---|
2991 | 3033 | for (level = 1; level <= max_level; level++) |
---|
2992 | | - wm[level] = max_t(uint16_t, wm[level], DIV_ROUND_UP(min, 5)); |
---|
| 3034 | + wm[level] = max_t(u16, wm[level], DIV_ROUND_UP(min, 5)); |
---|
2993 | 3035 | |
---|
2994 | 3036 | return true; |
---|
2995 | 3037 | } |
---|
.. | .. |
---|
3009 | 3051 | if (!changed) |
---|
3010 | 3052 | return; |
---|
3011 | 3053 | |
---|
3012 | | - DRM_DEBUG_KMS("WM latency values increased to avoid potential underruns\n"); |
---|
| 3054 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 3055 | + "WM latency values increased to avoid potential underruns\n"); |
---|
3013 | 3056 | intel_print_wm_latency(dev_priv, "Primary", dev_priv->wm.pri_latency); |
---|
3014 | 3057 | intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency); |
---|
3015 | 3058 | intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); |
---|
.. | .. |
---|
3037 | 3080 | dev_priv->wm.spr_latency[3] = 0; |
---|
3038 | 3081 | dev_priv->wm.cur_latency[3] = 0; |
---|
3039 | 3082 | |
---|
3040 | | - DRM_DEBUG_KMS("LP3 watermarks disabled due to potential for lost interrupts\n"); |
---|
| 3083 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 3084 | + "LP3 watermarks disabled due to potential for lost interrupts\n"); |
---|
3041 | 3085 | intel_print_wm_latency(dev_priv, "Primary", dev_priv->wm.pri_latency); |
---|
3042 | 3086 | intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency); |
---|
3043 | 3087 | intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); |
---|
.. | .. |
---|
3059 | 3103 | intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency); |
---|
3060 | 3104 | intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); |
---|
3061 | 3105 | |
---|
3062 | | - if (IS_GEN6(dev_priv)) { |
---|
| 3106 | + if (IS_GEN(dev_priv, 6)) { |
---|
3063 | 3107 | snb_wm_latency_quirk(dev_priv); |
---|
3064 | 3108 | snb_wm_lp3_irq_quirk(dev_priv); |
---|
3065 | 3109 | } |
---|
.. | .. |
---|
3071 | 3115 | intel_print_wm_latency(dev_priv, "Gen9 Plane", dev_priv->wm.skl_latency); |
---|
3072 | 3116 | } |
---|
3073 | 3117 | |
---|
3074 | | -static bool ilk_validate_pipe_wm(struct drm_device *dev, |
---|
| 3118 | +static bool ilk_validate_pipe_wm(const struct drm_i915_private *dev_priv, |
---|
3075 | 3119 | struct intel_pipe_wm *pipe_wm) |
---|
3076 | 3120 | { |
---|
3077 | 3121 | /* LP0 watermark maximums depend on this pipe alone */ |
---|
.. | .. |
---|
3083 | 3127 | struct ilk_wm_maximums max; |
---|
3084 | 3128 | |
---|
3085 | 3129 | /* LP0 watermarks always use 1/2 DDB partitioning */ |
---|
3086 | | - ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); |
---|
| 3130 | + ilk_compute_wm_maximums(dev_priv, 0, &config, INTEL_DDB_PART_1_2, &max); |
---|
3087 | 3131 | |
---|
3088 | 3132 | /* At least LP0 must be valid */ |
---|
3089 | 3133 | if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) { |
---|
3090 | | - DRM_DEBUG_KMS("LP0 watermark invalid\n"); |
---|
| 3134 | + drm_dbg_kms(&dev_priv->drm, "LP0 watermark invalid\n"); |
---|
3091 | 3135 | return false; |
---|
3092 | 3136 | } |
---|
3093 | 3137 | |
---|
.. | .. |
---|
3095 | 3139 | } |
---|
3096 | 3140 | |
---|
3097 | 3141 | /* Compute new watermarks for the pipe */ |
---|
3098 | | -static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) |
---|
| 3142 | +static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state) |
---|
3099 | 3143 | { |
---|
3100 | | - struct drm_atomic_state *state = cstate->base.state; |
---|
3101 | | - struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); |
---|
| 3144 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
| 3145 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
3102 | 3146 | struct intel_pipe_wm *pipe_wm; |
---|
3103 | | - struct drm_device *dev = state->dev; |
---|
3104 | | - const struct drm_i915_private *dev_priv = to_i915(dev); |
---|
3105 | | - struct drm_plane *plane; |
---|
3106 | | - const struct drm_plane_state *plane_state; |
---|
| 3147 | + struct intel_plane *plane; |
---|
| 3148 | + const struct intel_plane_state *plane_state; |
---|
3107 | 3149 | const struct intel_plane_state *pristate = NULL; |
---|
3108 | 3150 | const struct intel_plane_state *sprstate = NULL; |
---|
3109 | 3151 | const struct intel_plane_state *curstate = NULL; |
---|
3110 | 3152 | int level, max_level = ilk_wm_max_level(dev_priv), usable_level; |
---|
3111 | 3153 | struct ilk_wm_maximums max; |
---|
3112 | 3154 | |
---|
3113 | | - pipe_wm = &cstate->wm.ilk.optimal; |
---|
| 3155 | + pipe_wm = &crtc_state->wm.ilk.optimal; |
---|
3114 | 3156 | |
---|
3115 | | - drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, &cstate->base) { |
---|
3116 | | - const struct intel_plane_state *ps = to_intel_plane_state(plane_state); |
---|
3117 | | - |
---|
3118 | | - if (plane->type == DRM_PLANE_TYPE_PRIMARY) |
---|
3119 | | - pristate = ps; |
---|
3120 | | - else if (plane->type == DRM_PLANE_TYPE_OVERLAY) |
---|
3121 | | - sprstate = ps; |
---|
3122 | | - else if (plane->type == DRM_PLANE_TYPE_CURSOR) |
---|
3123 | | - curstate = ps; |
---|
| 3157 | + intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) { |
---|
| 3158 | + if (plane->base.type == DRM_PLANE_TYPE_PRIMARY) |
---|
| 3159 | + pristate = plane_state; |
---|
| 3160 | + else if (plane->base.type == DRM_PLANE_TYPE_OVERLAY) |
---|
| 3161 | + sprstate = plane_state; |
---|
| 3162 | + else if (plane->base.type == DRM_PLANE_TYPE_CURSOR) |
---|
| 3163 | + curstate = plane_state; |
---|
3124 | 3164 | } |
---|
3125 | 3165 | |
---|
3126 | | - pipe_wm->pipe_enabled = cstate->base.active; |
---|
| 3166 | + pipe_wm->pipe_enabled = crtc_state->hw.active; |
---|
3127 | 3167 | if (sprstate) { |
---|
3128 | | - pipe_wm->sprites_enabled = sprstate->base.visible; |
---|
3129 | | - pipe_wm->sprites_scaled = sprstate->base.visible && |
---|
3130 | | - (drm_rect_width(&sprstate->base.dst) != drm_rect_width(&sprstate->base.src) >> 16 || |
---|
3131 | | - drm_rect_height(&sprstate->base.dst) != drm_rect_height(&sprstate->base.src) >> 16); |
---|
| 3168 | + pipe_wm->sprites_enabled = sprstate->uapi.visible; |
---|
| 3169 | + pipe_wm->sprites_scaled = sprstate->uapi.visible && |
---|
| 3170 | + (drm_rect_width(&sprstate->uapi.dst) != drm_rect_width(&sprstate->uapi.src) >> 16 || |
---|
| 3171 | + drm_rect_height(&sprstate->uapi.dst) != drm_rect_height(&sprstate->uapi.src) >> 16); |
---|
3132 | 3172 | } |
---|
3133 | 3173 | |
---|
3134 | 3174 | usable_level = max_level; |
---|
.. | .. |
---|
3142 | 3182 | usable_level = 0; |
---|
3143 | 3183 | |
---|
3144 | 3184 | memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm)); |
---|
3145 | | - ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, |
---|
| 3185 | + ilk_compute_wm_level(dev_priv, crtc, 0, crtc_state, |
---|
3146 | 3186 | pristate, sprstate, curstate, &pipe_wm->wm[0]); |
---|
3147 | 3187 | |
---|
3148 | | - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) |
---|
3149 | | - pipe_wm->linetime = hsw_compute_linetime_wm(cstate); |
---|
3150 | | - |
---|
3151 | | - if (!ilk_validate_pipe_wm(dev, pipe_wm)) |
---|
| 3188 | + if (!ilk_validate_pipe_wm(dev_priv, pipe_wm)) |
---|
3152 | 3189 | return -EINVAL; |
---|
3153 | 3190 | |
---|
3154 | 3191 | ilk_compute_wm_reg_maximums(dev_priv, 1, &max); |
---|
.. | .. |
---|
3156 | 3193 | for (level = 1; level <= usable_level; level++) { |
---|
3157 | 3194 | struct intel_wm_level *wm = &pipe_wm->wm[level]; |
---|
3158 | 3195 | |
---|
3159 | | - ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, |
---|
| 3196 | + ilk_compute_wm_level(dev_priv, crtc, level, crtc_state, |
---|
3160 | 3197 | pristate, sprstate, curstate, wm); |
---|
3161 | 3198 | |
---|
3162 | 3199 | /* |
---|
.. | .. |
---|
3178 | 3215 | * state and the new state. These can be programmed to the hardware |
---|
3179 | 3216 | * immediately. |
---|
3180 | 3217 | */ |
---|
3181 | | -static int ilk_compute_intermediate_wm(struct drm_device *dev, |
---|
3182 | | - struct intel_crtc *intel_crtc, |
---|
3183 | | - struct intel_crtc_state *newstate) |
---|
| 3218 | +static int ilk_compute_intermediate_wm(struct intel_crtc_state *newstate) |
---|
3184 | 3219 | { |
---|
| 3220 | + struct intel_crtc *intel_crtc = to_intel_crtc(newstate->uapi.crtc); |
---|
| 3221 | + struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); |
---|
3185 | 3222 | struct intel_pipe_wm *a = &newstate->wm.ilk.intermediate; |
---|
3186 | 3223 | struct intel_atomic_state *intel_state = |
---|
3187 | | - to_intel_atomic_state(newstate->base.state); |
---|
| 3224 | + to_intel_atomic_state(newstate->uapi.state); |
---|
3188 | 3225 | const struct intel_crtc_state *oldstate = |
---|
3189 | 3226 | intel_atomic_get_old_crtc_state(intel_state, intel_crtc); |
---|
3190 | 3227 | const struct intel_pipe_wm *b = &oldstate->wm.ilk.optimal; |
---|
3191 | | - int level, max_level = ilk_wm_max_level(to_i915(dev)); |
---|
| 3228 | + int level, max_level = ilk_wm_max_level(dev_priv); |
---|
3192 | 3229 | |
---|
3193 | 3230 | /* |
---|
3194 | 3231 | * Start with the final, target watermarks, then combine with the |
---|
.. | .. |
---|
3196 | 3233 | * and after the vblank. |
---|
3197 | 3234 | */ |
---|
3198 | 3235 | *a = newstate->wm.ilk.optimal; |
---|
3199 | | - if (!newstate->base.active || drm_atomic_crtc_needs_modeset(&newstate->base)) |
---|
| 3236 | + if (!newstate->hw.active || drm_atomic_crtc_needs_modeset(&newstate->uapi) || |
---|
| 3237 | + intel_state->skip_intermediate_wm) |
---|
3200 | 3238 | return 0; |
---|
3201 | 3239 | |
---|
3202 | 3240 | a->pipe_enabled |= b->pipe_enabled; |
---|
.. | .. |
---|
3220 | 3258 | * there's no safe way to transition from the old state to |
---|
3221 | 3259 | * the new state, so we need to fail the atomic transaction. |
---|
3222 | 3260 | */ |
---|
3223 | | - if (!ilk_validate_pipe_wm(dev, a)) |
---|
| 3261 | + if (!ilk_validate_pipe_wm(dev_priv, a)) |
---|
3224 | 3262 | return -EINVAL; |
---|
3225 | 3263 | |
---|
3226 | 3264 | /* |
---|
.. | .. |
---|
3236 | 3274 | /* |
---|
3237 | 3275 | * Merge the watermarks from all active pipes for a specific level. |
---|
3238 | 3276 | */ |
---|
3239 | | -static void ilk_merge_wm_level(struct drm_device *dev, |
---|
| 3277 | +static void ilk_merge_wm_level(struct drm_i915_private *dev_priv, |
---|
3240 | 3278 | int level, |
---|
3241 | 3279 | struct intel_wm_level *ret_wm) |
---|
3242 | 3280 | { |
---|
.. | .. |
---|
3244 | 3282 | |
---|
3245 | 3283 | ret_wm->enable = true; |
---|
3246 | 3284 | |
---|
3247 | | - for_each_intel_crtc(dev, intel_crtc) { |
---|
| 3285 | + for_each_intel_crtc(&dev_priv->drm, intel_crtc) { |
---|
3248 | 3286 | const struct intel_pipe_wm *active = &intel_crtc->wm.active.ilk; |
---|
3249 | 3287 | const struct intel_wm_level *wm = &active->wm[level]; |
---|
3250 | 3288 | |
---|
.. | .. |
---|
3269 | 3307 | /* |
---|
3270 | 3308 | * Merge all low power watermarks for all active pipes. |
---|
3271 | 3309 | */ |
---|
3272 | | -static void ilk_wm_merge(struct drm_device *dev, |
---|
| 3310 | +static void ilk_wm_merge(struct drm_i915_private *dev_priv, |
---|
3273 | 3311 | const struct intel_wm_config *config, |
---|
3274 | 3312 | const struct ilk_wm_maximums *max, |
---|
3275 | 3313 | struct intel_pipe_wm *merged) |
---|
3276 | 3314 | { |
---|
3277 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
3278 | 3315 | int level, max_level = ilk_wm_max_level(dev_priv); |
---|
3279 | 3316 | int last_enabled_level = max_level; |
---|
3280 | 3317 | |
---|
.. | .. |
---|
3290 | 3327 | for (level = 1; level <= max_level; level++) { |
---|
3291 | 3328 | struct intel_wm_level *wm = &merged->wm[level]; |
---|
3292 | 3329 | |
---|
3293 | | - ilk_merge_wm_level(dev, level, wm); |
---|
| 3330 | + ilk_merge_wm_level(dev_priv, level, wm); |
---|
3294 | 3331 | |
---|
3295 | 3332 | if (level > last_enabled_level) |
---|
3296 | 3333 | wm->enable = false; |
---|
.. | .. |
---|
3315 | 3352 | * What we should check here is whether FBC can be |
---|
3316 | 3353 | * enabled sometime later. |
---|
3317 | 3354 | */ |
---|
3318 | | - if (IS_GEN5(dev_priv) && !merged->fbc_wm_enabled && |
---|
| 3355 | + if (IS_GEN(dev_priv, 5) && !merged->fbc_wm_enabled && |
---|
3319 | 3356 | intel_fbc_is_active(dev_priv)) { |
---|
3320 | 3357 | for (level = 2; level <= max_level; level++) { |
---|
3321 | 3358 | struct intel_wm_level *wm = &merged->wm[level]; |
---|
.. | .. |
---|
3332 | 3369 | } |
---|
3333 | 3370 | |
---|
3334 | 3371 | /* The value we need to program into the WM_LPx latency field */ |
---|
3335 | | -static unsigned int ilk_wm_lp_latency(struct drm_device *dev, int level) |
---|
| 3372 | +static unsigned int ilk_wm_lp_latency(struct drm_i915_private *dev_priv, |
---|
| 3373 | + int level) |
---|
3336 | 3374 | { |
---|
3337 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
3338 | | - |
---|
3339 | 3375 | if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) |
---|
3340 | 3376 | return 2 * level; |
---|
3341 | 3377 | else |
---|
3342 | 3378 | return dev_priv->wm.pri_latency[level]; |
---|
3343 | 3379 | } |
---|
3344 | 3380 | |
---|
3345 | | -static void ilk_compute_wm_results(struct drm_device *dev, |
---|
| 3381 | +static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, |
---|
3346 | 3382 | const struct intel_pipe_wm *merged, |
---|
3347 | 3383 | enum intel_ddb_partitioning partitioning, |
---|
3348 | 3384 | struct ilk_wm_values *results) |
---|
3349 | 3385 | { |
---|
3350 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
3351 | 3386 | struct intel_crtc *intel_crtc; |
---|
3352 | 3387 | int level, wm_lp; |
---|
3353 | 3388 | |
---|
.. | .. |
---|
3367 | 3402 | * disabled. Doing otherwise could cause underruns. |
---|
3368 | 3403 | */ |
---|
3369 | 3404 | results->wm_lp[wm_lp - 1] = |
---|
3370 | | - (ilk_wm_lp_latency(dev, level) << WM1_LP_LATENCY_SHIFT) | |
---|
| 3405 | + (ilk_wm_lp_latency(dev_priv, level) << WM1_LP_LATENCY_SHIFT) | |
---|
3371 | 3406 | (r->pri_val << WM1_LP_SR_SHIFT) | |
---|
3372 | 3407 | r->cur_val; |
---|
3373 | 3408 | |
---|
.. | .. |
---|
3386 | 3421 | * level is disabled. Doing otherwise could cause underruns. |
---|
3387 | 3422 | */ |
---|
3388 | 3423 | if (INTEL_GEN(dev_priv) <= 6 && r->spr_val) { |
---|
3389 | | - WARN_ON(wm_lp != 1); |
---|
| 3424 | + drm_WARN_ON(&dev_priv->drm, wm_lp != 1); |
---|
3390 | 3425 | results->wm_lp_spr[wm_lp - 1] = WM1S_LP_EN | r->spr_val; |
---|
3391 | 3426 | } else |
---|
3392 | 3427 | results->wm_lp_spr[wm_lp - 1] = r->spr_val; |
---|
3393 | 3428 | } |
---|
3394 | 3429 | |
---|
3395 | 3430 | /* LP0 register values */ |
---|
3396 | | - for_each_intel_crtc(dev, intel_crtc) { |
---|
| 3431 | + for_each_intel_crtc(&dev_priv->drm, intel_crtc) { |
---|
3397 | 3432 | enum pipe pipe = intel_crtc->pipe; |
---|
3398 | | - const struct intel_wm_level *r = |
---|
3399 | | - &intel_crtc->wm.active.ilk.wm[0]; |
---|
| 3433 | + const struct intel_pipe_wm *pipe_wm = &intel_crtc->wm.active.ilk; |
---|
| 3434 | + const struct intel_wm_level *r = &pipe_wm->wm[0]; |
---|
3400 | 3435 | |
---|
3401 | | - if (WARN_ON(!r->enable)) |
---|
| 3436 | + if (drm_WARN_ON(&dev_priv->drm, !r->enable)) |
---|
3402 | 3437 | continue; |
---|
3403 | | - |
---|
3404 | | - results->wm_linetime[pipe] = intel_crtc->wm.active.ilk.linetime; |
---|
3405 | 3438 | |
---|
3406 | 3439 | results->wm_pipe[pipe] = |
---|
3407 | 3440 | (r->pri_val << WM0_PIPE_PLANE_SHIFT) | |
---|
.. | .. |
---|
3412 | 3445 | |
---|
3413 | 3446 | /* Find the result with the highest level enabled. Check for enable_fbc_wm in |
---|
3414 | 3447 | * case both are at the same level. Prefer r1 in case they're the same. */ |
---|
3415 | | -static struct intel_pipe_wm *ilk_find_best_result(struct drm_device *dev, |
---|
3416 | | - struct intel_pipe_wm *r1, |
---|
3417 | | - struct intel_pipe_wm *r2) |
---|
| 3448 | +static struct intel_pipe_wm * |
---|
| 3449 | +ilk_find_best_result(struct drm_i915_private *dev_priv, |
---|
| 3450 | + struct intel_pipe_wm *r1, |
---|
| 3451 | + struct intel_pipe_wm *r2) |
---|
3418 | 3452 | { |
---|
3419 | | - int level, max_level = ilk_wm_max_level(to_i915(dev)); |
---|
| 3453 | + int level, max_level = ilk_wm_max_level(dev_priv); |
---|
3420 | 3454 | int level1 = 0, level2 = 0; |
---|
3421 | 3455 | |
---|
3422 | 3456 | for (level = 1; level <= max_level; level++) { |
---|
.. | .. |
---|
3440 | 3474 | |
---|
3441 | 3475 | /* dirty bits used to track which watermarks need changes */ |
---|
3442 | 3476 | #define WM_DIRTY_PIPE(pipe) (1 << (pipe)) |
---|
3443 | | -#define WM_DIRTY_LINETIME(pipe) (1 << (8 + (pipe))) |
---|
3444 | 3477 | #define WM_DIRTY_LP(wm_lp) (1 << (15 + (wm_lp))) |
---|
3445 | 3478 | #define WM_DIRTY_LP_ALL (WM_DIRTY_LP(1) | WM_DIRTY_LP(2) | WM_DIRTY_LP(3)) |
---|
3446 | 3479 | #define WM_DIRTY_FBC (1 << 24) |
---|
.. | .. |
---|
3455 | 3488 | int wm_lp; |
---|
3456 | 3489 | |
---|
3457 | 3490 | for_each_pipe(dev_priv, pipe) { |
---|
3458 | | - if (old->wm_linetime[pipe] != new->wm_linetime[pipe]) { |
---|
3459 | | - dirty |= WM_DIRTY_LINETIME(pipe); |
---|
3460 | | - /* Must disable LP1+ watermarks too */ |
---|
3461 | | - dirty |= WM_DIRTY_LP_ALL; |
---|
3462 | | - } |
---|
3463 | | - |
---|
3464 | 3491 | if (old->wm_pipe[pipe] != new->wm_pipe[pipe]) { |
---|
3465 | 3492 | dirty |= WM_DIRTY_PIPE(pipe); |
---|
3466 | 3493 | /* Must disable LP1+ watermarks too */ |
---|
.. | .. |
---|
3537 | 3564 | { |
---|
3538 | 3565 | struct ilk_wm_values *previous = &dev_priv->wm.hw; |
---|
3539 | 3566 | unsigned int dirty; |
---|
3540 | | - uint32_t val; |
---|
| 3567 | + u32 val; |
---|
3541 | 3568 | |
---|
3542 | 3569 | dirty = ilk_compute_wm_dirty(dev_priv, previous, results); |
---|
3543 | 3570 | if (!dirty) |
---|
.. | .. |
---|
3551 | 3578 | I915_WRITE(WM0_PIPEB_ILK, results->wm_pipe[1]); |
---|
3552 | 3579 | if (dirty & WM_DIRTY_PIPE(PIPE_C)) |
---|
3553 | 3580 | I915_WRITE(WM0_PIPEC_IVB, results->wm_pipe[2]); |
---|
3554 | | - |
---|
3555 | | - if (dirty & WM_DIRTY_LINETIME(PIPE_A)) |
---|
3556 | | - I915_WRITE(PIPE_WM_LINETIME(PIPE_A), results->wm_linetime[0]); |
---|
3557 | | - if (dirty & WM_DIRTY_LINETIME(PIPE_B)) |
---|
3558 | | - I915_WRITE(PIPE_WM_LINETIME(PIPE_B), results->wm_linetime[1]); |
---|
3559 | | - if (dirty & WM_DIRTY_LINETIME(PIPE_C)) |
---|
3560 | | - I915_WRITE(PIPE_WM_LINETIME(PIPE_C), results->wm_linetime[2]); |
---|
3561 | 3581 | |
---|
3562 | 3582 | if (dirty & WM_DIRTY_DDB) { |
---|
3563 | 3583 | if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { |
---|
.. | .. |
---|
3607 | 3627 | dev_priv->wm.hw = *results; |
---|
3608 | 3628 | } |
---|
3609 | 3629 | |
---|
3610 | | -bool ilk_disable_lp_wm(struct drm_device *dev) |
---|
| 3630 | +bool ilk_disable_lp_wm(struct drm_i915_private *dev_priv) |
---|
3611 | 3631 | { |
---|
3612 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
3613 | | - |
---|
3614 | 3632 | return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL); |
---|
3615 | 3633 | } |
---|
3616 | 3634 | |
---|
3617 | | -static u8 intel_enabled_dbuf_slices_num(struct drm_i915_private *dev_priv) |
---|
| 3635 | +u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *dev_priv) |
---|
3618 | 3636 | { |
---|
3619 | | - u8 enabled_slices; |
---|
| 3637 | + int i; |
---|
| 3638 | + int max_slices = INTEL_INFO(dev_priv)->num_supported_dbuf_slices; |
---|
| 3639 | + u8 enabled_slices_mask = 0; |
---|
3620 | 3640 | |
---|
3621 | | - /* Slice 1 will always be enabled */ |
---|
3622 | | - enabled_slices = 1; |
---|
| 3641 | + for (i = 0; i < max_slices; i++) { |
---|
| 3642 | + if (I915_READ(DBUF_CTL_S(i)) & DBUF_POWER_STATE) |
---|
| 3643 | + enabled_slices_mask |= BIT(i); |
---|
| 3644 | + } |
---|
3623 | 3645 | |
---|
3624 | | - /* Gen prior to GEN11 have only one DBuf slice */ |
---|
3625 | | - if (INTEL_GEN(dev_priv) < 11) |
---|
3626 | | - return enabled_slices; |
---|
3627 | | - |
---|
3628 | | - if (I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE) |
---|
3629 | | - enabled_slices++; |
---|
3630 | | - |
---|
3631 | | - return enabled_slices; |
---|
| 3646 | + return enabled_slices_mask; |
---|
3632 | 3647 | } |
---|
3633 | 3648 | |
---|
3634 | 3649 | /* |
---|
3635 | 3650 | * FIXME: We still don't have the proper code detect if we need to apply the WA, |
---|
3636 | 3651 | * so assume we'll always need it in order to avoid underruns. |
---|
3637 | 3652 | */ |
---|
3638 | | -static bool skl_needs_memory_bw_wa(struct intel_atomic_state *state) |
---|
| 3653 | +static bool skl_needs_memory_bw_wa(struct drm_i915_private *dev_priv) |
---|
3639 | 3654 | { |
---|
3640 | | - struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
3641 | | - |
---|
3642 | | - if (IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv)) |
---|
3643 | | - return true; |
---|
3644 | | - |
---|
3645 | | - return false; |
---|
| 3655 | + return IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv); |
---|
3646 | 3656 | } |
---|
3647 | 3657 | |
---|
3648 | 3658 | static bool |
---|
3649 | 3659 | intel_has_sagv(struct drm_i915_private *dev_priv) |
---|
3650 | 3660 | { |
---|
3651 | | - if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) || |
---|
3652 | | - IS_CANNONLAKE(dev_priv)) |
---|
3653 | | - return true; |
---|
| 3661 | + return (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) && |
---|
| 3662 | + dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED; |
---|
| 3663 | +} |
---|
3654 | 3664 | |
---|
3655 | | - if (IS_SKYLAKE(dev_priv) && |
---|
3656 | | - dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED) |
---|
3657 | | - return true; |
---|
| 3665 | +static void |
---|
| 3666 | +skl_setup_sagv_block_time(struct drm_i915_private *dev_priv) |
---|
| 3667 | +{ |
---|
| 3668 | + if (INTEL_GEN(dev_priv) >= 12) { |
---|
| 3669 | + u32 val = 0; |
---|
| 3670 | + int ret; |
---|
3658 | 3671 | |
---|
3659 | | - return false; |
---|
| 3672 | + ret = sandybridge_pcode_read(dev_priv, |
---|
| 3673 | + GEN12_PCODE_READ_SAGV_BLOCK_TIME_US, |
---|
| 3674 | + &val, NULL); |
---|
| 3675 | + if (!ret) { |
---|
| 3676 | + dev_priv->sagv_block_time_us = val; |
---|
| 3677 | + return; |
---|
| 3678 | + } |
---|
| 3679 | + |
---|
| 3680 | + drm_dbg(&dev_priv->drm, "Couldn't read SAGV block time!\n"); |
---|
| 3681 | + } else if (IS_GEN(dev_priv, 11)) { |
---|
| 3682 | + dev_priv->sagv_block_time_us = 10; |
---|
| 3683 | + return; |
---|
| 3684 | + } else if (IS_GEN(dev_priv, 10)) { |
---|
| 3685 | + dev_priv->sagv_block_time_us = 20; |
---|
| 3686 | + return; |
---|
| 3687 | + } else if (IS_GEN(dev_priv, 9)) { |
---|
| 3688 | + dev_priv->sagv_block_time_us = 30; |
---|
| 3689 | + return; |
---|
| 3690 | + } else { |
---|
| 3691 | + MISSING_CASE(INTEL_GEN(dev_priv)); |
---|
| 3692 | + } |
---|
| 3693 | + |
---|
| 3694 | + /* Default to an unusable block time */ |
---|
| 3695 | + dev_priv->sagv_block_time_us = -1; |
---|
3660 | 3696 | } |
---|
3661 | 3697 | |
---|
3662 | 3698 | /* |
---|
.. | .. |
---|
3681 | 3717 | if (dev_priv->sagv_status == I915_SAGV_ENABLED) |
---|
3682 | 3718 | return 0; |
---|
3683 | 3719 | |
---|
3684 | | - DRM_DEBUG_KMS("Enabling the SAGV\n"); |
---|
3685 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
3686 | | - |
---|
| 3720 | + drm_dbg_kms(&dev_priv->drm, "Enabling SAGV\n"); |
---|
3687 | 3721 | ret = sandybridge_pcode_write(dev_priv, GEN9_PCODE_SAGV_CONTROL, |
---|
3688 | 3722 | GEN9_SAGV_ENABLE); |
---|
3689 | 3723 | |
---|
3690 | | - /* We don't need to wait for the SAGV when enabling */ |
---|
3691 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
| 3724 | + /* We don't need to wait for SAGV when enabling */ |
---|
3692 | 3725 | |
---|
3693 | 3726 | /* |
---|
3694 | 3727 | * Some skl systems, pre-release machines in particular, |
---|
3695 | | - * don't actually have an SAGV. |
---|
| 3728 | + * don't actually have SAGV. |
---|
3696 | 3729 | */ |
---|
3697 | 3730 | if (IS_SKYLAKE(dev_priv) && ret == -ENXIO) { |
---|
3698 | | - DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); |
---|
| 3731 | + drm_dbg(&dev_priv->drm, "No SAGV found on system, ignoring\n"); |
---|
3699 | 3732 | dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; |
---|
3700 | 3733 | return 0; |
---|
3701 | 3734 | } else if (ret < 0) { |
---|
3702 | | - DRM_ERROR("Failed to enable the SAGV\n"); |
---|
| 3735 | + drm_err(&dev_priv->drm, "Failed to enable SAGV\n"); |
---|
3703 | 3736 | return ret; |
---|
3704 | 3737 | } |
---|
3705 | 3738 | |
---|
.. | .. |
---|
3718 | 3751 | if (dev_priv->sagv_status == I915_SAGV_DISABLED) |
---|
3719 | 3752 | return 0; |
---|
3720 | 3753 | |
---|
3721 | | - DRM_DEBUG_KMS("Disabling the SAGV\n"); |
---|
3722 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
3723 | | - |
---|
| 3754 | + drm_dbg_kms(&dev_priv->drm, "Disabling SAGV\n"); |
---|
3724 | 3755 | /* bspec says to keep retrying for at least 1 ms */ |
---|
3725 | 3756 | ret = skl_pcode_request(dev_priv, GEN9_PCODE_SAGV_CONTROL, |
---|
3726 | 3757 | GEN9_SAGV_DISABLE, |
---|
3727 | 3758 | GEN9_SAGV_IS_DISABLED, GEN9_SAGV_IS_DISABLED, |
---|
3728 | 3759 | 1); |
---|
3729 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
3730 | | - |
---|
3731 | 3760 | /* |
---|
3732 | 3761 | * Some skl systems, pre-release machines in particular, |
---|
3733 | | - * don't actually have an SAGV. |
---|
| 3762 | + * don't actually have SAGV. |
---|
3734 | 3763 | */ |
---|
3735 | 3764 | if (IS_SKYLAKE(dev_priv) && ret == -ENXIO) { |
---|
3736 | | - DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); |
---|
| 3765 | + drm_dbg(&dev_priv->drm, "No SAGV found on system, ignoring\n"); |
---|
3737 | 3766 | dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED; |
---|
3738 | 3767 | return 0; |
---|
3739 | 3768 | } else if (ret < 0) { |
---|
3740 | | - DRM_ERROR("Failed to disable the SAGV (%d)\n", ret); |
---|
| 3769 | + drm_err(&dev_priv->drm, "Failed to disable SAGV (%d)\n", ret); |
---|
3741 | 3770 | return ret; |
---|
3742 | 3771 | } |
---|
3743 | 3772 | |
---|
.. | .. |
---|
3745 | 3774 | return 0; |
---|
3746 | 3775 | } |
---|
3747 | 3776 | |
---|
3748 | | -bool intel_can_enable_sagv(struct drm_atomic_state *state) |
---|
| 3777 | +void intel_sagv_pre_plane_update(struct intel_atomic_state *state) |
---|
3749 | 3778 | { |
---|
3750 | | - struct drm_device *dev = state->dev; |
---|
3751 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
3752 | | - struct intel_atomic_state *intel_state = to_intel_atomic_state(state); |
---|
3753 | | - struct intel_crtc *crtc; |
---|
| 3779 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
| 3780 | + const struct intel_bw_state *new_bw_state; |
---|
| 3781 | + const struct intel_bw_state *old_bw_state; |
---|
| 3782 | + u32 new_mask = 0; |
---|
| 3783 | + |
---|
| 3784 | + /* |
---|
| 3785 | + * Just return if we can't control SAGV or don't have it. |
---|
| 3786 | + * This is different from situation when we have SAGV but just can't |
---|
| 3787 | + * afford it due to DBuf limitation - in case if SAGV is completely |
---|
| 3788 | + * disabled in a BIOS, we are not even allowed to send a PCode request, |
---|
| 3789 | + * as it will throw an error. So have to check it here. |
---|
| 3790 | + */ |
---|
| 3791 | + if (!intel_has_sagv(dev_priv)) |
---|
| 3792 | + return; |
---|
| 3793 | + |
---|
| 3794 | + new_bw_state = intel_atomic_get_new_bw_state(state); |
---|
| 3795 | + if (!new_bw_state) |
---|
| 3796 | + return; |
---|
| 3797 | + |
---|
| 3798 | + if (INTEL_GEN(dev_priv) < 11 && !intel_can_enable_sagv(dev_priv, new_bw_state)) { |
---|
| 3799 | + intel_disable_sagv(dev_priv); |
---|
| 3800 | + return; |
---|
| 3801 | + } |
---|
| 3802 | + |
---|
| 3803 | + old_bw_state = intel_atomic_get_old_bw_state(state); |
---|
| 3804 | + /* |
---|
| 3805 | + * Nothing to mask |
---|
| 3806 | + */ |
---|
| 3807 | + if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask) |
---|
| 3808 | + return; |
---|
| 3809 | + |
---|
| 3810 | + new_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask; |
---|
| 3811 | + |
---|
| 3812 | + /* |
---|
| 3813 | + * If new mask is zero - means there is nothing to mask, |
---|
| 3814 | + * we can only unmask, which should be done in unmask. |
---|
| 3815 | + */ |
---|
| 3816 | + if (!new_mask) |
---|
| 3817 | + return; |
---|
| 3818 | + |
---|
| 3819 | + /* |
---|
| 3820 | + * Restrict required qgv points before updating the configuration. |
---|
| 3821 | + * According to BSpec we can't mask and unmask qgv points at the same |
---|
| 3822 | + * time. Also masking should be done before updating the configuration |
---|
| 3823 | + * and unmasking afterwards. |
---|
| 3824 | + */ |
---|
| 3825 | + icl_pcode_restrict_qgv_points(dev_priv, new_mask); |
---|
| 3826 | +} |
---|
| 3827 | + |
---|
| 3828 | +void intel_sagv_post_plane_update(struct intel_atomic_state *state) |
---|
| 3829 | +{ |
---|
| 3830 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
| 3831 | + const struct intel_bw_state *new_bw_state; |
---|
| 3832 | + const struct intel_bw_state *old_bw_state; |
---|
| 3833 | + u32 new_mask = 0; |
---|
| 3834 | + |
---|
| 3835 | + /* |
---|
| 3836 | + * Just return if we can't control SAGV or don't have it. |
---|
| 3837 | + * This is different from situation when we have SAGV but just can't |
---|
| 3838 | + * afford it due to DBuf limitation - in case if SAGV is completely |
---|
| 3839 | + * disabled in a BIOS, we are not even allowed to send a PCode request, |
---|
| 3840 | + * as it will throw an error. So have to check it here. |
---|
| 3841 | + */ |
---|
| 3842 | + if (!intel_has_sagv(dev_priv)) |
---|
| 3843 | + return; |
---|
| 3844 | + |
---|
| 3845 | + new_bw_state = intel_atomic_get_new_bw_state(state); |
---|
| 3846 | + if (!new_bw_state) |
---|
| 3847 | + return; |
---|
| 3848 | + |
---|
| 3849 | + if (INTEL_GEN(dev_priv) < 11 && intel_can_enable_sagv(dev_priv, new_bw_state)) { |
---|
| 3850 | + intel_enable_sagv(dev_priv); |
---|
| 3851 | + return; |
---|
| 3852 | + } |
---|
| 3853 | + |
---|
| 3854 | + old_bw_state = intel_atomic_get_old_bw_state(state); |
---|
| 3855 | + /* |
---|
| 3856 | + * Nothing to unmask |
---|
| 3857 | + */ |
---|
| 3858 | + if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask) |
---|
| 3859 | + return; |
---|
| 3860 | + |
---|
| 3861 | + new_mask = new_bw_state->qgv_points_mask; |
---|
| 3862 | + |
---|
| 3863 | + /* |
---|
| 3864 | + * Allow required qgv points after updating the configuration. |
---|
| 3865 | + * According to BSpec we can't mask and unmask qgv points at the same |
---|
| 3866 | + * time. Also masking should be done before updating the configuration |
---|
| 3867 | + * and unmasking afterwards. |
---|
| 3868 | + */ |
---|
| 3869 | + icl_pcode_restrict_qgv_points(dev_priv, new_mask); |
---|
| 3870 | +} |
---|
| 3871 | + |
---|
| 3872 | +static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) |
---|
| 3873 | +{ |
---|
| 3874 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
| 3875 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
3754 | 3876 | struct intel_plane *plane; |
---|
3755 | | - struct intel_crtc_state *cstate; |
---|
3756 | | - enum pipe pipe; |
---|
| 3877 | + const struct intel_plane_state *plane_state; |
---|
3757 | 3878 | int level, latency; |
---|
3758 | | - int sagv_block_time_us; |
---|
3759 | 3879 | |
---|
3760 | 3880 | if (!intel_has_sagv(dev_priv)) |
---|
3761 | 3881 | return false; |
---|
3762 | 3882 | |
---|
3763 | | - if (IS_GEN9(dev_priv)) |
---|
3764 | | - sagv_block_time_us = 30; |
---|
3765 | | - else if (IS_GEN10(dev_priv)) |
---|
3766 | | - sagv_block_time_us = 20; |
---|
3767 | | - else |
---|
3768 | | - sagv_block_time_us = 10; |
---|
3769 | | - |
---|
3770 | | - /* |
---|
3771 | | - * SKL+ workaround: bspec recommends we disable the SAGV when we have |
---|
3772 | | - * more then one pipe enabled |
---|
3773 | | - * |
---|
3774 | | - * If there are no active CRTCs, no additional checks need be performed |
---|
3775 | | - */ |
---|
3776 | | - if (hweight32(intel_state->active_crtcs) == 0) |
---|
| 3883 | + if (!crtc_state->hw.active) |
---|
3777 | 3884 | return true; |
---|
3778 | | - else if (hweight32(intel_state->active_crtcs) > 1) |
---|
| 3885 | + |
---|
| 3886 | + if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) |
---|
3779 | 3887 | return false; |
---|
3780 | 3888 | |
---|
3781 | | - /* Since we're now guaranteed to only have one active CRTC... */ |
---|
3782 | | - pipe = ffs(intel_state->active_crtcs) - 1; |
---|
3783 | | - crtc = intel_get_crtc_for_pipe(dev_priv, pipe); |
---|
3784 | | - cstate = to_intel_crtc_state(crtc->base.state); |
---|
3785 | | - |
---|
3786 | | - if (crtc->base.state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) |
---|
3787 | | - return false; |
---|
3788 | | - |
---|
3789 | | - for_each_intel_plane_on_crtc(dev, crtc, plane) { |
---|
3790 | | - struct skl_plane_wm *wm = |
---|
3791 | | - &cstate->wm.skl.optimal.planes[plane->id]; |
---|
| 3889 | + intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) { |
---|
| 3890 | + const struct skl_plane_wm *wm = |
---|
| 3891 | + &crtc_state->wm.skl.optimal.planes[plane->id]; |
---|
3792 | 3892 | |
---|
3793 | 3893 | /* Skip this plane if it's not enabled */ |
---|
3794 | 3894 | if (!wm->wm[0].plane_en) |
---|
.. | .. |
---|
3801 | 3901 | |
---|
3802 | 3902 | latency = dev_priv->wm.skl_latency[level]; |
---|
3803 | 3903 | |
---|
3804 | | - if (skl_needs_memory_bw_wa(intel_state) && |
---|
3805 | | - plane->base.state->fb->modifier == |
---|
| 3904 | + if (skl_needs_memory_bw_wa(dev_priv) && |
---|
| 3905 | + plane_state->uapi.fb->modifier == |
---|
3806 | 3906 | I915_FORMAT_MOD_X_TILED) |
---|
3807 | 3907 | latency += 15; |
---|
3808 | 3908 | |
---|
3809 | 3909 | /* |
---|
3810 | 3910 | * If any of the planes on this pipe don't enable wm levels that |
---|
3811 | 3911 | * incur memory latencies higher than sagv_block_time_us we |
---|
3812 | | - * can't enable the SAGV. |
---|
| 3912 | + * can't enable SAGV. |
---|
3813 | 3913 | */ |
---|
3814 | | - if (latency < sagv_block_time_us) |
---|
| 3914 | + if (latency < dev_priv->sagv_block_time_us) |
---|
3815 | 3915 | return false; |
---|
3816 | 3916 | } |
---|
3817 | 3917 | |
---|
3818 | 3918 | return true; |
---|
3819 | 3919 | } |
---|
3820 | 3920 | |
---|
3821 | | -static unsigned int intel_get_ddb_size(struct drm_i915_private *dev_priv, |
---|
3822 | | - const struct intel_crtc_state *cstate, |
---|
3823 | | - const unsigned int total_data_rate, |
---|
3824 | | - const int num_active, |
---|
3825 | | - struct skl_ddb_allocation *ddb) |
---|
| 3921 | +static bool tgl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) |
---|
3826 | 3922 | { |
---|
3827 | | - const struct drm_display_mode *adjusted_mode; |
---|
3828 | | - u64 total_data_bw; |
---|
3829 | | - u16 ddb_size = INTEL_INFO(dev_priv)->ddb_size; |
---|
| 3923 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
| 3924 | + enum plane_id plane_id; |
---|
3830 | 3925 | |
---|
3831 | | - WARN_ON(ddb_size == 0); |
---|
| 3926 | + if (!crtc_state->hw.active) |
---|
| 3927 | + return true; |
---|
| 3928 | + |
---|
| 3929 | + for_each_plane_id_on_crtc(crtc, plane_id) { |
---|
| 3930 | + const struct skl_ddb_entry *plane_alloc = |
---|
| 3931 | + &crtc_state->wm.skl.plane_ddb_y[plane_id]; |
---|
| 3932 | + const struct skl_plane_wm *wm = |
---|
| 3933 | + &crtc_state->wm.skl.optimal.planes[plane_id]; |
---|
| 3934 | + |
---|
| 3935 | + if (skl_ddb_entry_size(plane_alloc) < wm->sagv_wm0.min_ddb_alloc) |
---|
| 3936 | + return false; |
---|
| 3937 | + } |
---|
| 3938 | + |
---|
| 3939 | + return true; |
---|
| 3940 | +} |
---|
| 3941 | + |
---|
| 3942 | +static bool intel_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) |
---|
| 3943 | +{ |
---|
| 3944 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
| 3945 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 3946 | + |
---|
| 3947 | + if (INTEL_GEN(dev_priv) >= 12) |
---|
| 3948 | + return tgl_crtc_can_enable_sagv(crtc_state); |
---|
| 3949 | + else |
---|
| 3950 | + return skl_crtc_can_enable_sagv(crtc_state); |
---|
| 3951 | +} |
---|
| 3952 | + |
---|
| 3953 | +bool intel_can_enable_sagv(struct drm_i915_private *dev_priv, |
---|
| 3954 | + const struct intel_bw_state *bw_state) |
---|
| 3955 | +{ |
---|
| 3956 | + if (INTEL_GEN(dev_priv) < 11 && |
---|
| 3957 | + bw_state->active_pipes && !is_power_of_2(bw_state->active_pipes)) |
---|
| 3958 | + return false; |
---|
| 3959 | + |
---|
| 3960 | + return bw_state->pipe_sagv_reject == 0; |
---|
| 3961 | +} |
---|
| 3962 | + |
---|
| 3963 | +static int intel_compute_sagv_mask(struct intel_atomic_state *state) |
---|
| 3964 | +{ |
---|
| 3965 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
| 3966 | + int ret; |
---|
| 3967 | + struct intel_crtc *crtc; |
---|
| 3968 | + struct intel_crtc_state *new_crtc_state; |
---|
| 3969 | + struct intel_bw_state *new_bw_state = NULL; |
---|
| 3970 | + const struct intel_bw_state *old_bw_state = NULL; |
---|
| 3971 | + int i; |
---|
| 3972 | + |
---|
| 3973 | + for_each_new_intel_crtc_in_state(state, crtc, |
---|
| 3974 | + new_crtc_state, i) { |
---|
| 3975 | + new_bw_state = intel_atomic_get_bw_state(state); |
---|
| 3976 | + if (IS_ERR(new_bw_state)) |
---|
| 3977 | + return PTR_ERR(new_bw_state); |
---|
| 3978 | + |
---|
| 3979 | + old_bw_state = intel_atomic_get_old_bw_state(state); |
---|
| 3980 | + |
---|
| 3981 | + if (intel_crtc_can_enable_sagv(new_crtc_state)) |
---|
| 3982 | + new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe); |
---|
| 3983 | + else |
---|
| 3984 | + new_bw_state->pipe_sagv_reject |= BIT(crtc->pipe); |
---|
| 3985 | + } |
---|
| 3986 | + |
---|
| 3987 | + if (!new_bw_state) |
---|
| 3988 | + return 0; |
---|
| 3989 | + |
---|
| 3990 | + new_bw_state->active_pipes = |
---|
| 3991 | + intel_calc_active_pipes(state, old_bw_state->active_pipes); |
---|
| 3992 | + |
---|
| 3993 | + if (new_bw_state->active_pipes != old_bw_state->active_pipes) { |
---|
| 3994 | + ret = intel_atomic_lock_global_state(&new_bw_state->base); |
---|
| 3995 | + if (ret) |
---|
| 3996 | + return ret; |
---|
| 3997 | + } |
---|
| 3998 | + |
---|
| 3999 | + if (intel_can_enable_sagv(dev_priv, new_bw_state) != |
---|
| 4000 | + intel_can_enable_sagv(dev_priv, old_bw_state)) { |
---|
| 4001 | + ret = intel_atomic_serialize_global_state(&new_bw_state->base); |
---|
| 4002 | + if (ret) |
---|
| 4003 | + return ret; |
---|
| 4004 | + } else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) { |
---|
| 4005 | + ret = intel_atomic_lock_global_state(&new_bw_state->base); |
---|
| 4006 | + if (ret) |
---|
| 4007 | + return ret; |
---|
| 4008 | + } |
---|
| 4009 | + |
---|
| 4010 | + for_each_new_intel_crtc_in_state(state, crtc, |
---|
| 4011 | + new_crtc_state, i) { |
---|
| 4012 | + struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal; |
---|
| 4013 | + |
---|
| 4014 | + /* |
---|
| 4015 | + * We store use_sagv_wm in the crtc state rather than relying on |
---|
| 4016 | + * that bw state since we have no convenient way to get at the |
---|
| 4017 | + * latter from the plane commit hooks (especially in the legacy |
---|
| 4018 | + * cursor case) |
---|
| 4019 | + */ |
---|
| 4020 | + pipe_wm->use_sagv_wm = INTEL_GEN(dev_priv) >= 12 && |
---|
| 4021 | + intel_can_enable_sagv(dev_priv, new_bw_state); |
---|
| 4022 | + } |
---|
| 4023 | + |
---|
| 4024 | + return 0; |
---|
| 4025 | +} |
---|
| 4026 | + |
---|
| 4027 | +/* |
---|
| 4028 | + * Calculate initial DBuf slice offset, based on slice size |
---|
| 4029 | + * and mask(i.e if slice size is 1024 and second slice is enabled |
---|
| 4030 | + * offset would be 1024) |
---|
| 4031 | + */ |
---|
| 4032 | +static unsigned int |
---|
| 4033 | +icl_get_first_dbuf_slice_offset(u32 dbuf_slice_mask, |
---|
| 4034 | + u32 slice_size, |
---|
| 4035 | + u32 ddb_size) |
---|
| 4036 | +{ |
---|
| 4037 | + unsigned int offset = 0; |
---|
| 4038 | + |
---|
| 4039 | + if (!dbuf_slice_mask) |
---|
| 4040 | + return 0; |
---|
| 4041 | + |
---|
| 4042 | + offset = (ffs(dbuf_slice_mask) - 1) * slice_size; |
---|
| 4043 | + |
---|
| 4044 | + WARN_ON(offset >= ddb_size); |
---|
| 4045 | + return offset; |
---|
| 4046 | +} |
---|
| 4047 | + |
---|
| 4048 | +u16 intel_get_ddb_size(struct drm_i915_private *dev_priv) |
---|
| 4049 | +{ |
---|
| 4050 | + u16 ddb_size = INTEL_INFO(dev_priv)->ddb_size; |
---|
| 4051 | + drm_WARN_ON(&dev_priv->drm, ddb_size == 0); |
---|
3832 | 4052 | |
---|
3833 | 4053 | if (INTEL_GEN(dev_priv) < 11) |
---|
3834 | 4054 | return ddb_size - 4; /* 4 blocks for bypass path allocation */ |
---|
3835 | 4055 | |
---|
3836 | | - adjusted_mode = &cstate->base.adjusted_mode; |
---|
3837 | | - total_data_bw = (u64)total_data_rate * drm_mode_vrefresh(adjusted_mode); |
---|
3838 | | - |
---|
3839 | | - /* |
---|
3840 | | - * 12GB/s is maximum BW supported by single DBuf slice. |
---|
3841 | | - */ |
---|
3842 | | - if (total_data_bw >= GBps(12) || num_active > 1) { |
---|
3843 | | - ddb->enabled_slices = 2; |
---|
3844 | | - } else { |
---|
3845 | | - ddb->enabled_slices = 1; |
---|
3846 | | - ddb_size /= 2; |
---|
3847 | | - } |
---|
3848 | | - |
---|
3849 | 4056 | return ddb_size; |
---|
3850 | 4057 | } |
---|
3851 | 4058 | |
---|
3852 | | -static void |
---|
3853 | | -skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, |
---|
3854 | | - const struct intel_crtc_state *cstate, |
---|
3855 | | - const unsigned int total_data_rate, |
---|
3856 | | - struct skl_ddb_allocation *ddb, |
---|
| 4059 | +u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *dev_priv, |
---|
| 4060 | + const struct skl_ddb_entry *entry) |
---|
| 4061 | +{ |
---|
| 4062 | + u32 slice_mask = 0; |
---|
| 4063 | + u16 ddb_size = intel_get_ddb_size(dev_priv); |
---|
| 4064 | + u16 num_supported_slices = INTEL_INFO(dev_priv)->num_supported_dbuf_slices; |
---|
| 4065 | + u16 slice_size = ddb_size / num_supported_slices; |
---|
| 4066 | + u16 start_slice; |
---|
| 4067 | + u16 end_slice; |
---|
| 4068 | + |
---|
| 4069 | + if (!skl_ddb_entry_size(entry)) |
---|
| 4070 | + return 0; |
---|
| 4071 | + |
---|
| 4072 | + start_slice = entry->start / slice_size; |
---|
| 4073 | + end_slice = (entry->end - 1) / slice_size; |
---|
| 4074 | + |
---|
| 4075 | + /* |
---|
| 4076 | + * Per plane DDB entry can in a really worst case be on multiple slices |
---|
| 4077 | + * but single entry is anyway contigious. |
---|
| 4078 | + */ |
---|
| 4079 | + while (start_slice <= end_slice) { |
---|
| 4080 | + slice_mask |= BIT(start_slice); |
---|
| 4081 | + start_slice++; |
---|
| 4082 | + } |
---|
| 4083 | + |
---|
| 4084 | + return slice_mask; |
---|
| 4085 | +} |
---|
| 4086 | + |
---|
| 4087 | +static u8 skl_compute_dbuf_slices(const struct intel_crtc_state *crtc_state, |
---|
| 4088 | + u8 active_pipes); |
---|
| 4089 | + |
---|
| 4090 | +static int |
---|
| 4091 | +skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv, |
---|
| 4092 | + const struct intel_crtc_state *crtc_state, |
---|
| 4093 | + const u64 total_data_rate, |
---|
3857 | 4094 | struct skl_ddb_entry *alloc, /* out */ |
---|
3858 | 4095 | int *num_active /* out */) |
---|
3859 | 4096 | { |
---|
3860 | | - struct drm_atomic_state *state = cstate->base.state; |
---|
| 4097 | + struct drm_atomic_state *state = crtc_state->uapi.state; |
---|
3861 | 4098 | struct intel_atomic_state *intel_state = to_intel_atomic_state(state); |
---|
3862 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
3863 | | - struct drm_crtc *for_crtc = cstate->base.crtc; |
---|
3864 | | - unsigned int pipe_size, ddb_size; |
---|
3865 | | - int nth_active_pipe; |
---|
| 4099 | + struct drm_crtc *for_crtc = crtc_state->uapi.crtc; |
---|
| 4100 | + const struct intel_crtc *crtc; |
---|
| 4101 | + u32 pipe_width = 0, total_width_in_range = 0, width_before_pipe_in_range = 0; |
---|
| 4102 | + enum pipe for_pipe = to_intel_crtc(for_crtc)->pipe; |
---|
| 4103 | + struct intel_dbuf_state *new_dbuf_state = |
---|
| 4104 | + intel_atomic_get_new_dbuf_state(intel_state); |
---|
| 4105 | + const struct intel_dbuf_state *old_dbuf_state = |
---|
| 4106 | + intel_atomic_get_old_dbuf_state(intel_state); |
---|
| 4107 | + u8 active_pipes = new_dbuf_state->active_pipes; |
---|
| 4108 | + u16 ddb_size; |
---|
| 4109 | + u32 ddb_range_size; |
---|
| 4110 | + u32 i; |
---|
| 4111 | + u32 dbuf_slice_mask; |
---|
| 4112 | + u32 offset; |
---|
| 4113 | + u32 slice_size; |
---|
| 4114 | + u32 total_slice_mask; |
---|
| 4115 | + u32 start, end; |
---|
| 4116 | + int ret; |
---|
3866 | 4117 | |
---|
3867 | | - if (WARN_ON(!state) || !cstate->base.active) { |
---|
| 4118 | + *num_active = hweight8(active_pipes); |
---|
| 4119 | + |
---|
| 4120 | + if (!crtc_state->hw.active) { |
---|
3868 | 4121 | alloc->start = 0; |
---|
3869 | 4122 | alloc->end = 0; |
---|
3870 | | - *num_active = hweight32(dev_priv->active_crtcs); |
---|
3871 | | - return; |
---|
| 4123 | + return 0; |
---|
3872 | 4124 | } |
---|
3873 | 4125 | |
---|
3874 | | - if (intel_state->active_pipe_changes) |
---|
3875 | | - *num_active = hweight32(intel_state->active_crtcs); |
---|
3876 | | - else |
---|
3877 | | - *num_active = hweight32(dev_priv->active_crtcs); |
---|
| 4126 | + ddb_size = intel_get_ddb_size(dev_priv); |
---|
3878 | 4127 | |
---|
3879 | | - ddb_size = intel_get_ddb_size(dev_priv, cstate, total_data_rate, |
---|
3880 | | - *num_active, ddb); |
---|
| 4128 | + slice_size = ddb_size / INTEL_INFO(dev_priv)->num_supported_dbuf_slices; |
---|
3881 | 4129 | |
---|
3882 | 4130 | /* |
---|
3883 | | - * If the state doesn't change the active CRTC's, then there's |
---|
3884 | | - * no need to recalculate; the existing pipe allocation limits |
---|
3885 | | - * should remain unchanged. Note that we're safe from racing |
---|
3886 | | - * commits since any racing commit that changes the active CRTC |
---|
3887 | | - * list would need to grab _all_ crtc locks, including the one |
---|
3888 | | - * we currently hold. |
---|
| 4131 | + * If the state doesn't change the active CRTC's or there is no |
---|
| 4132 | + * modeset request, then there's no need to recalculate; |
---|
| 4133 | + * the existing pipe allocation limits should remain unchanged. |
---|
| 4134 | + * Note that we're safe from racing commits since any racing commit |
---|
| 4135 | + * that changes the active CRTC list or do modeset would need to |
---|
| 4136 | + * grab _all_ crtc locks, including the one we currently hold. |
---|
3889 | 4137 | */ |
---|
3890 | | - if (!intel_state->active_pipe_changes) { |
---|
| 4138 | + if (old_dbuf_state->active_pipes == new_dbuf_state->active_pipes && |
---|
| 4139 | + !dev_priv->wm.distrust_bios_wm) { |
---|
3891 | 4140 | /* |
---|
3892 | 4141 | * alloc may be cleared by clear_intel_crtc_state, |
---|
3893 | 4142 | * copy from old state to be sure |
---|
| 4143 | + * |
---|
| 4144 | + * FIXME get rid of this mess |
---|
3894 | 4145 | */ |
---|
3895 | 4146 | *alloc = to_intel_crtc_state(for_crtc->state)->wm.skl.ddb; |
---|
3896 | | - return; |
---|
| 4147 | + return 0; |
---|
3897 | 4148 | } |
---|
3898 | 4149 | |
---|
3899 | | - nth_active_pipe = hweight32(intel_state->active_crtcs & |
---|
3900 | | - (drm_crtc_mask(for_crtc) - 1)); |
---|
3901 | | - pipe_size = ddb_size / hweight32(intel_state->active_crtcs); |
---|
3902 | | - alloc->start = nth_active_pipe * ddb_size / *num_active; |
---|
3903 | | - alloc->end = alloc->start + pipe_size; |
---|
| 4150 | + /* |
---|
| 4151 | + * Get allowed DBuf slices for correspondent pipe and platform. |
---|
| 4152 | + */ |
---|
| 4153 | + dbuf_slice_mask = skl_compute_dbuf_slices(crtc_state, active_pipes); |
---|
| 4154 | + |
---|
| 4155 | + /* |
---|
| 4156 | + * Figure out at which DBuf slice we start, i.e if we start at Dbuf S2 |
---|
| 4157 | + * and slice size is 1024, the offset would be 1024 |
---|
| 4158 | + */ |
---|
| 4159 | + offset = icl_get_first_dbuf_slice_offset(dbuf_slice_mask, |
---|
| 4160 | + slice_size, ddb_size); |
---|
| 4161 | + |
---|
| 4162 | + /* |
---|
| 4163 | + * Figure out total size of allowed DBuf slices, which is basically |
---|
| 4164 | + * a number of allowed slices for that pipe multiplied by slice size. |
---|
| 4165 | + * Inside of this |
---|
| 4166 | + * range ddb entries are still allocated in proportion to display width. |
---|
| 4167 | + */ |
---|
| 4168 | + ddb_range_size = hweight8(dbuf_slice_mask) * slice_size; |
---|
| 4169 | + |
---|
| 4170 | + /* |
---|
| 4171 | + * Watermark/ddb requirement highly depends upon width of the |
---|
| 4172 | + * framebuffer, So instead of allocating DDB equally among pipes |
---|
| 4173 | + * distribute DDB based on resolution/width of the display. |
---|
| 4174 | + */ |
---|
| 4175 | + total_slice_mask = dbuf_slice_mask; |
---|
| 4176 | + for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) { |
---|
| 4177 | + const struct drm_display_mode *adjusted_mode = |
---|
| 4178 | + &crtc_state->hw.adjusted_mode; |
---|
| 4179 | + enum pipe pipe = crtc->pipe; |
---|
| 4180 | + int hdisplay, vdisplay; |
---|
| 4181 | + u32 pipe_dbuf_slice_mask; |
---|
| 4182 | + |
---|
| 4183 | + if (!crtc_state->hw.active) |
---|
| 4184 | + continue; |
---|
| 4185 | + |
---|
| 4186 | + pipe_dbuf_slice_mask = skl_compute_dbuf_slices(crtc_state, |
---|
| 4187 | + active_pipes); |
---|
| 4188 | + |
---|
| 4189 | + /* |
---|
| 4190 | + * According to BSpec pipe can share one dbuf slice with another |
---|
| 4191 | + * pipes or pipe can use multiple dbufs, in both cases we |
---|
| 4192 | + * account for other pipes only if they have exactly same mask. |
---|
| 4193 | + * However we need to account how many slices we should enable |
---|
| 4194 | + * in total. |
---|
| 4195 | + */ |
---|
| 4196 | + total_slice_mask |= pipe_dbuf_slice_mask; |
---|
| 4197 | + |
---|
| 4198 | + /* |
---|
| 4199 | + * Do not account pipes using other slice sets |
---|
| 4200 | + * luckily as of current BSpec slice sets do not partially |
---|
| 4201 | + * intersect(pipes share either same one slice or same slice set |
---|
| 4202 | + * i.e no partial intersection), so it is enough to check for |
---|
| 4203 | + * equality for now. |
---|
| 4204 | + */ |
---|
| 4205 | + if (dbuf_slice_mask != pipe_dbuf_slice_mask) |
---|
| 4206 | + continue; |
---|
| 4207 | + |
---|
| 4208 | + drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay); |
---|
| 4209 | + |
---|
| 4210 | + total_width_in_range += hdisplay; |
---|
| 4211 | + |
---|
| 4212 | + if (pipe < for_pipe) |
---|
| 4213 | + width_before_pipe_in_range += hdisplay; |
---|
| 4214 | + else if (pipe == for_pipe) |
---|
| 4215 | + pipe_width = hdisplay; |
---|
| 4216 | + } |
---|
| 4217 | + |
---|
| 4218 | + /* |
---|
| 4219 | + * FIXME: For now we always enable slice S1 as per |
---|
| 4220 | + * the Bspec display initialization sequence. |
---|
| 4221 | + */ |
---|
| 4222 | + new_dbuf_state->enabled_slices = total_slice_mask | BIT(DBUF_S1); |
---|
| 4223 | + |
---|
| 4224 | + if (old_dbuf_state->enabled_slices != new_dbuf_state->enabled_slices) { |
---|
| 4225 | + ret = intel_atomic_serialize_global_state(&new_dbuf_state->base); |
---|
| 4226 | + if (ret) |
---|
| 4227 | + return ret; |
---|
| 4228 | + } |
---|
| 4229 | + |
---|
| 4230 | + start = ddb_range_size * width_before_pipe_in_range / total_width_in_range; |
---|
| 4231 | + end = ddb_range_size * |
---|
| 4232 | + (width_before_pipe_in_range + pipe_width) / total_width_in_range; |
---|
| 4233 | + |
---|
| 4234 | + alloc->start = offset + start; |
---|
| 4235 | + alloc->end = offset + end; |
---|
| 4236 | + |
---|
| 4237 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 4238 | + "[CRTC:%d:%s] dbuf slices 0x%x, ddb (%d - %d), active pipes 0x%x\n", |
---|
| 4239 | + for_crtc->base.id, for_crtc->name, |
---|
| 4240 | + dbuf_slice_mask, alloc->start, alloc->end, active_pipes); |
---|
| 4241 | + |
---|
| 4242 | + return 0; |
---|
3904 | 4243 | } |
---|
3905 | 4244 | |
---|
3906 | | -static unsigned int skl_cursor_allocation(int num_active) |
---|
3907 | | -{ |
---|
3908 | | - if (num_active == 1) |
---|
3909 | | - return 32; |
---|
| 4245 | +static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state, |
---|
| 4246 | + int width, const struct drm_format_info *format, |
---|
| 4247 | + u64 modifier, unsigned int rotation, |
---|
| 4248 | + u32 plane_pixel_rate, struct skl_wm_params *wp, |
---|
| 4249 | + int color_plane); |
---|
| 4250 | +static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, |
---|
| 4251 | + int level, |
---|
| 4252 | + unsigned int latency, |
---|
| 4253 | + const struct skl_wm_params *wp, |
---|
| 4254 | + const struct skl_wm_level *result_prev, |
---|
| 4255 | + struct skl_wm_level *result /* out */); |
---|
3910 | 4256 | |
---|
3911 | | - return 8; |
---|
| 4257 | +static unsigned int |
---|
| 4258 | +skl_cursor_allocation(const struct intel_crtc_state *crtc_state, |
---|
| 4259 | + int num_active) |
---|
| 4260 | +{ |
---|
| 4261 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
| 4262 | + int level, max_level = ilk_wm_max_level(dev_priv); |
---|
| 4263 | + struct skl_wm_level wm = {}; |
---|
| 4264 | + int ret, min_ddb_alloc = 0; |
---|
| 4265 | + struct skl_wm_params wp; |
---|
| 4266 | + |
---|
| 4267 | + ret = skl_compute_wm_params(crtc_state, 256, |
---|
| 4268 | + drm_format_info(DRM_FORMAT_ARGB8888), |
---|
| 4269 | + DRM_FORMAT_MOD_LINEAR, |
---|
| 4270 | + DRM_MODE_ROTATE_0, |
---|
| 4271 | + crtc_state->pixel_rate, &wp, 0); |
---|
| 4272 | + drm_WARN_ON(&dev_priv->drm, ret); |
---|
| 4273 | + |
---|
| 4274 | + for (level = 0; level <= max_level; level++) { |
---|
| 4275 | + unsigned int latency = dev_priv->wm.skl_latency[level]; |
---|
| 4276 | + |
---|
| 4277 | + skl_compute_plane_wm(crtc_state, level, latency, &wp, &wm, &wm); |
---|
| 4278 | + if (wm.min_ddb_alloc == U16_MAX) |
---|
| 4279 | + break; |
---|
| 4280 | + |
---|
| 4281 | + min_ddb_alloc = wm.min_ddb_alloc; |
---|
| 4282 | + } |
---|
| 4283 | + |
---|
| 4284 | + return max(num_active == 1 ? 32 : 8, min_ddb_alloc); |
---|
3912 | 4285 | } |
---|
3913 | 4286 | |
---|
3914 | 4287 | static void skl_ddb_entry_init_from_hw(struct drm_i915_private *dev_priv, |
---|
3915 | 4288 | struct skl_ddb_entry *entry, u32 reg) |
---|
3916 | 4289 | { |
---|
3917 | | - u16 mask; |
---|
3918 | 4290 | |
---|
3919 | | - if (INTEL_GEN(dev_priv) >= 11) |
---|
3920 | | - mask = ICL_DDB_ENTRY_MASK; |
---|
3921 | | - else |
---|
3922 | | - mask = SKL_DDB_ENTRY_MASK; |
---|
3923 | | - entry->start = reg & mask; |
---|
3924 | | - entry->end = (reg >> DDB_ENTRY_END_SHIFT) & mask; |
---|
| 4291 | + entry->start = reg & DDB_ENTRY_MASK; |
---|
| 4292 | + entry->end = (reg >> DDB_ENTRY_END_SHIFT) & DDB_ENTRY_MASK; |
---|
3925 | 4293 | |
---|
3926 | 4294 | if (entry->end) |
---|
3927 | 4295 | entry->end += 1; |
---|
.. | .. |
---|
3931 | 4299 | skl_ddb_get_hw_plane_state(struct drm_i915_private *dev_priv, |
---|
3932 | 4300 | const enum pipe pipe, |
---|
3933 | 4301 | const enum plane_id plane_id, |
---|
3934 | | - struct skl_ddb_allocation *ddb /* out */) |
---|
| 4302 | + struct skl_ddb_entry *ddb_y, |
---|
| 4303 | + struct skl_ddb_entry *ddb_uv) |
---|
3935 | 4304 | { |
---|
3936 | | - u32 val, val2 = 0; |
---|
3937 | | - int fourcc, pixel_format; |
---|
| 4305 | + u32 val, val2; |
---|
| 4306 | + u32 fourcc = 0; |
---|
3938 | 4307 | |
---|
3939 | 4308 | /* Cursor doesn't support NV12/planar, so no extra calculation needed */ |
---|
3940 | 4309 | if (plane_id == PLANE_CURSOR) { |
---|
3941 | 4310 | val = I915_READ(CUR_BUF_CFG(pipe)); |
---|
3942 | | - skl_ddb_entry_init_from_hw(dev_priv, |
---|
3943 | | - &ddb->plane[pipe][plane_id], val); |
---|
| 4311 | + skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val); |
---|
3944 | 4312 | return; |
---|
3945 | 4313 | } |
---|
3946 | 4314 | |
---|
3947 | 4315 | val = I915_READ(PLANE_CTL(pipe, plane_id)); |
---|
3948 | 4316 | |
---|
3949 | 4317 | /* No DDB allocated for disabled planes */ |
---|
3950 | | - if (!(val & PLANE_CTL_ENABLE)) |
---|
3951 | | - return; |
---|
| 4318 | + if (val & PLANE_CTL_ENABLE) |
---|
| 4319 | + fourcc = skl_format_to_fourcc(val & PLANE_CTL_FORMAT_MASK, |
---|
| 4320 | + val & PLANE_CTL_ORDER_RGBX, |
---|
| 4321 | + val & PLANE_CTL_ALPHA_MASK); |
---|
3952 | 4322 | |
---|
3953 | | - pixel_format = val & PLANE_CTL_FORMAT_MASK; |
---|
3954 | | - fourcc = skl_format_to_fourcc(pixel_format, |
---|
3955 | | - val & PLANE_CTL_ORDER_RGBX, |
---|
3956 | | - val & PLANE_CTL_ALPHA_MASK); |
---|
3957 | | - |
---|
3958 | | - val = I915_READ(PLANE_BUF_CFG(pipe, plane_id)); |
---|
3959 | | - val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id)); |
---|
3960 | | - |
---|
3961 | | - if (fourcc == DRM_FORMAT_NV12) { |
---|
3962 | | - skl_ddb_entry_init_from_hw(dev_priv, |
---|
3963 | | - &ddb->plane[pipe][plane_id], val2); |
---|
3964 | | - skl_ddb_entry_init_from_hw(dev_priv, |
---|
3965 | | - &ddb->uv_plane[pipe][plane_id], val); |
---|
| 4323 | + if (INTEL_GEN(dev_priv) >= 11) { |
---|
| 4324 | + val = I915_READ(PLANE_BUF_CFG(pipe, plane_id)); |
---|
| 4325 | + skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val); |
---|
3966 | 4326 | } else { |
---|
3967 | | - skl_ddb_entry_init_from_hw(dev_priv, |
---|
3968 | | - &ddb->plane[pipe][plane_id], val); |
---|
| 4327 | + val = I915_READ(PLANE_BUF_CFG(pipe, plane_id)); |
---|
| 4328 | + val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id)); |
---|
| 4329 | + |
---|
| 4330 | + if (fourcc && |
---|
| 4331 | + drm_format_info_is_yuv_semiplanar(drm_format_info(fourcc))) |
---|
| 4332 | + swap(val, val2); |
---|
| 4333 | + |
---|
| 4334 | + skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val); |
---|
| 4335 | + skl_ddb_entry_init_from_hw(dev_priv, ddb_uv, val2); |
---|
3969 | 4336 | } |
---|
3970 | 4337 | } |
---|
3971 | 4338 | |
---|
3972 | | -void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, |
---|
3973 | | - struct skl_ddb_allocation *ddb /* out */) |
---|
| 4339 | +void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, |
---|
| 4340 | + struct skl_ddb_entry *ddb_y, |
---|
| 4341 | + struct skl_ddb_entry *ddb_uv) |
---|
3974 | 4342 | { |
---|
3975 | | - struct intel_crtc *crtc; |
---|
| 4343 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 4344 | + enum intel_display_power_domain power_domain; |
---|
| 4345 | + enum pipe pipe = crtc->pipe; |
---|
| 4346 | + intel_wakeref_t wakeref; |
---|
| 4347 | + enum plane_id plane_id; |
---|
3976 | 4348 | |
---|
3977 | | - memset(ddb, 0, sizeof(*ddb)); |
---|
| 4349 | + power_domain = POWER_DOMAIN_PIPE(pipe); |
---|
| 4350 | + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); |
---|
| 4351 | + if (!wakeref) |
---|
| 4352 | + return; |
---|
3978 | 4353 | |
---|
3979 | | - ddb->enabled_slices = intel_enabled_dbuf_slices_num(dev_priv); |
---|
| 4354 | + for_each_plane_id_on_crtc(crtc, plane_id) |
---|
| 4355 | + skl_ddb_get_hw_plane_state(dev_priv, pipe, |
---|
| 4356 | + plane_id, |
---|
| 4357 | + &ddb_y[plane_id], |
---|
| 4358 | + &ddb_uv[plane_id]); |
---|
3980 | 4359 | |
---|
3981 | | - for_each_intel_crtc(&dev_priv->drm, crtc) { |
---|
3982 | | - enum intel_display_power_domain power_domain; |
---|
3983 | | - enum plane_id plane_id; |
---|
3984 | | - enum pipe pipe = crtc->pipe; |
---|
3985 | | - |
---|
3986 | | - power_domain = POWER_DOMAIN_PIPE(pipe); |
---|
3987 | | - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) |
---|
3988 | | - continue; |
---|
3989 | | - |
---|
3990 | | - for_each_plane_id_on_crtc(crtc, plane_id) |
---|
3991 | | - skl_ddb_get_hw_plane_state(dev_priv, pipe, |
---|
3992 | | - plane_id, ddb); |
---|
3993 | | - |
---|
3994 | | - intel_display_power_put(dev_priv, power_domain); |
---|
3995 | | - } |
---|
| 4360 | + intel_display_power_put(dev_priv, power_domain, wakeref); |
---|
3996 | 4361 | } |
---|
3997 | 4362 | |
---|
3998 | 4363 | /* |
---|
.. | .. |
---|
4012 | 4377 | * Caller should take care of dividing & rounding off the value. |
---|
4013 | 4378 | */ |
---|
4014 | 4379 | static uint_fixed_16_16_t |
---|
4015 | | -skl_plane_downscale_amount(const struct intel_crtc_state *cstate, |
---|
4016 | | - const struct intel_plane_state *pstate) |
---|
| 4380 | +skl_plane_downscale_amount(const struct intel_crtc_state *crtc_state, |
---|
| 4381 | + const struct intel_plane_state *plane_state) |
---|
4017 | 4382 | { |
---|
4018 | | - struct intel_plane *plane = to_intel_plane(pstate->base.plane); |
---|
4019 | | - uint32_t src_w, src_h, dst_w, dst_h; |
---|
| 4383 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
| 4384 | + u32 src_w, src_h, dst_w, dst_h; |
---|
4020 | 4385 | uint_fixed_16_16_t fp_w_ratio, fp_h_ratio; |
---|
4021 | 4386 | uint_fixed_16_16_t downscale_h, downscale_w; |
---|
4022 | 4387 | |
---|
4023 | | - if (WARN_ON(!intel_wm_plane_visible(cstate, pstate))) |
---|
| 4388 | + if (drm_WARN_ON(&dev_priv->drm, |
---|
| 4389 | + !intel_wm_plane_visible(crtc_state, plane_state))) |
---|
4024 | 4390 | return u32_to_fixed16(0); |
---|
4025 | 4391 | |
---|
4026 | | - /* n.b., src is 16.16 fixed point, dst is whole integer */ |
---|
4027 | | - if (plane->id == PLANE_CURSOR) { |
---|
4028 | | - /* |
---|
4029 | | - * Cursors only support 0/180 degree rotation, |
---|
4030 | | - * hence no need to account for rotation here. |
---|
4031 | | - */ |
---|
4032 | | - src_w = pstate->base.src_w >> 16; |
---|
4033 | | - src_h = pstate->base.src_h >> 16; |
---|
4034 | | - dst_w = pstate->base.crtc_w; |
---|
4035 | | - dst_h = pstate->base.crtc_h; |
---|
4036 | | - } else { |
---|
4037 | | - /* |
---|
4038 | | - * Src coordinates are already rotated by 270 degrees for |
---|
4039 | | - * the 90/270 degree plane rotation cases (to match the |
---|
4040 | | - * GTT mapping), hence no need to account for rotation here. |
---|
4041 | | - */ |
---|
4042 | | - src_w = drm_rect_width(&pstate->base.src) >> 16; |
---|
4043 | | - src_h = drm_rect_height(&pstate->base.src) >> 16; |
---|
4044 | | - dst_w = drm_rect_width(&pstate->base.dst); |
---|
4045 | | - dst_h = drm_rect_height(&pstate->base.dst); |
---|
4046 | | - } |
---|
| 4392 | + /* |
---|
| 4393 | + * Src coordinates are already rotated by 270 degrees for |
---|
| 4394 | + * the 90/270 degree plane rotation cases (to match the |
---|
| 4395 | + * GTT mapping), hence no need to account for rotation here. |
---|
| 4396 | + * |
---|
| 4397 | + * n.b., src is 16.16 fixed point, dst is whole integer. |
---|
| 4398 | + */ |
---|
| 4399 | + src_w = drm_rect_width(&plane_state->uapi.src) >> 16; |
---|
| 4400 | + src_h = drm_rect_height(&plane_state->uapi.src) >> 16; |
---|
| 4401 | + dst_w = drm_rect_width(&plane_state->uapi.dst); |
---|
| 4402 | + dst_h = drm_rect_height(&plane_state->uapi.dst); |
---|
4047 | 4403 | |
---|
4048 | 4404 | fp_w_ratio = div_fixed16(src_w, dst_w); |
---|
4049 | 4405 | fp_h_ratio = div_fixed16(src_h, dst_h); |
---|
.. | .. |
---|
4053 | 4409 | return mul_fixed16(downscale_w, downscale_h); |
---|
4054 | 4410 | } |
---|
4055 | 4411 | |
---|
4056 | | -static uint_fixed_16_16_t |
---|
4057 | | -skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state) |
---|
| 4412 | +struct dbuf_slice_conf_entry { |
---|
| 4413 | + u8 active_pipes; |
---|
| 4414 | + u8 dbuf_mask[I915_MAX_PIPES]; |
---|
| 4415 | +}; |
---|
| 4416 | + |
---|
| 4417 | +/* |
---|
| 4418 | + * Table taken from Bspec 12716 |
---|
| 4419 | + * Pipes do have some preferred DBuf slice affinity, |
---|
| 4420 | + * plus there are some hardcoded requirements on how |
---|
| 4421 | + * those should be distributed for multipipe scenarios. |
---|
| 4422 | + * For more DBuf slices algorithm can get even more messy |
---|
| 4423 | + * and less readable, so decided to use a table almost |
---|
| 4424 | + * as is from BSpec itself - that way it is at least easier |
---|
| 4425 | + * to compare, change and check. |
---|
| 4426 | + */ |
---|
| 4427 | +static const struct dbuf_slice_conf_entry icl_allowed_dbufs[] = |
---|
| 4428 | +/* Autogenerated with igt/tools/intel_dbuf_map tool: */ |
---|
4058 | 4429 | { |
---|
4059 | | - uint_fixed_16_16_t pipe_downscale = u32_to_fixed16(1); |
---|
| 4430 | + { |
---|
| 4431 | + .active_pipes = BIT(PIPE_A), |
---|
| 4432 | + .dbuf_mask = { |
---|
| 4433 | + [PIPE_A] = BIT(DBUF_S1), |
---|
| 4434 | + }, |
---|
| 4435 | + }, |
---|
| 4436 | + { |
---|
| 4437 | + .active_pipes = BIT(PIPE_B), |
---|
| 4438 | + .dbuf_mask = { |
---|
| 4439 | + [PIPE_B] = BIT(DBUF_S1), |
---|
| 4440 | + }, |
---|
| 4441 | + }, |
---|
| 4442 | + { |
---|
| 4443 | + .active_pipes = BIT(PIPE_A) | BIT(PIPE_B), |
---|
| 4444 | + .dbuf_mask = { |
---|
| 4445 | + [PIPE_A] = BIT(DBUF_S1), |
---|
| 4446 | + [PIPE_B] = BIT(DBUF_S2), |
---|
| 4447 | + }, |
---|
| 4448 | + }, |
---|
| 4449 | + { |
---|
| 4450 | + .active_pipes = BIT(PIPE_C), |
---|
| 4451 | + .dbuf_mask = { |
---|
| 4452 | + [PIPE_C] = BIT(DBUF_S2), |
---|
| 4453 | + }, |
---|
| 4454 | + }, |
---|
| 4455 | + { |
---|
| 4456 | + .active_pipes = BIT(PIPE_A) | BIT(PIPE_C), |
---|
| 4457 | + .dbuf_mask = { |
---|
| 4458 | + [PIPE_A] = BIT(DBUF_S1), |
---|
| 4459 | + [PIPE_C] = BIT(DBUF_S2), |
---|
| 4460 | + }, |
---|
| 4461 | + }, |
---|
| 4462 | + { |
---|
| 4463 | + .active_pipes = BIT(PIPE_B) | BIT(PIPE_C), |
---|
| 4464 | + .dbuf_mask = { |
---|
| 4465 | + [PIPE_B] = BIT(DBUF_S1), |
---|
| 4466 | + [PIPE_C] = BIT(DBUF_S2), |
---|
| 4467 | + }, |
---|
| 4468 | + }, |
---|
| 4469 | + { |
---|
| 4470 | + .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), |
---|
| 4471 | + .dbuf_mask = { |
---|
| 4472 | + [PIPE_A] = BIT(DBUF_S1), |
---|
| 4473 | + [PIPE_B] = BIT(DBUF_S1), |
---|
| 4474 | + [PIPE_C] = BIT(DBUF_S2), |
---|
| 4475 | + }, |
---|
| 4476 | + }, |
---|
| 4477 | + {} |
---|
| 4478 | +}; |
---|
4060 | 4479 | |
---|
4061 | | - if (!crtc_state->base.enable) |
---|
4062 | | - return pipe_downscale; |
---|
4063 | | - |
---|
4064 | | - if (crtc_state->pch_pfit.enabled) { |
---|
4065 | | - uint32_t src_w, src_h, dst_w, dst_h; |
---|
4066 | | - uint32_t pfit_size = crtc_state->pch_pfit.size; |
---|
4067 | | - uint_fixed_16_16_t fp_w_ratio, fp_h_ratio; |
---|
4068 | | - uint_fixed_16_16_t downscale_h, downscale_w; |
---|
4069 | | - |
---|
4070 | | - src_w = crtc_state->pipe_src_w; |
---|
4071 | | - src_h = crtc_state->pipe_src_h; |
---|
4072 | | - dst_w = pfit_size >> 16; |
---|
4073 | | - dst_h = pfit_size & 0xffff; |
---|
4074 | | - |
---|
4075 | | - if (!dst_w || !dst_h) |
---|
4076 | | - return pipe_downscale; |
---|
4077 | | - |
---|
4078 | | - fp_w_ratio = div_fixed16(src_w, dst_w); |
---|
4079 | | - fp_h_ratio = div_fixed16(src_h, dst_h); |
---|
4080 | | - downscale_w = max_fixed16(fp_w_ratio, u32_to_fixed16(1)); |
---|
4081 | | - downscale_h = max_fixed16(fp_h_ratio, u32_to_fixed16(1)); |
---|
4082 | | - |
---|
4083 | | - pipe_downscale = mul_fixed16(downscale_w, downscale_h); |
---|
4084 | | - } |
---|
4085 | | - |
---|
4086 | | - return pipe_downscale; |
---|
4087 | | -} |
---|
4088 | | - |
---|
4089 | | -int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, |
---|
4090 | | - struct intel_crtc_state *cstate) |
---|
| 4480 | +/* |
---|
| 4481 | + * Table taken from Bspec 49255 |
---|
| 4482 | + * Pipes do have some preferred DBuf slice affinity, |
---|
| 4483 | + * plus there are some hardcoded requirements on how |
---|
| 4484 | + * those should be distributed for multipipe scenarios. |
---|
| 4485 | + * For more DBuf slices algorithm can get even more messy |
---|
| 4486 | + * and less readable, so decided to use a table almost |
---|
| 4487 | + * as is from BSpec itself - that way it is at least easier |
---|
| 4488 | + * to compare, change and check. |
---|
| 4489 | + */ |
---|
| 4490 | +static const struct dbuf_slice_conf_entry tgl_allowed_dbufs[] = |
---|
| 4491 | +/* Autogenerated with igt/tools/intel_dbuf_map tool: */ |
---|
4091 | 4492 | { |
---|
4092 | | - struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); |
---|
4093 | | - struct drm_crtc_state *crtc_state = &cstate->base; |
---|
4094 | | - struct drm_atomic_state *state = crtc_state->state; |
---|
4095 | | - struct drm_plane *plane; |
---|
4096 | | - const struct drm_plane_state *pstate; |
---|
4097 | | - struct intel_plane_state *intel_pstate; |
---|
4098 | | - int crtc_clock, dotclk; |
---|
4099 | | - uint32_t pipe_max_pixel_rate; |
---|
4100 | | - uint_fixed_16_16_t pipe_downscale; |
---|
4101 | | - uint_fixed_16_16_t max_downscale = u32_to_fixed16(1); |
---|
| 4493 | + { |
---|
| 4494 | + .active_pipes = BIT(PIPE_A), |
---|
| 4495 | + .dbuf_mask = { |
---|
| 4496 | + [PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2), |
---|
| 4497 | + }, |
---|
| 4498 | + }, |
---|
| 4499 | + { |
---|
| 4500 | + .active_pipes = BIT(PIPE_B), |
---|
| 4501 | + .dbuf_mask = { |
---|
| 4502 | + [PIPE_B] = BIT(DBUF_S1) | BIT(DBUF_S2), |
---|
| 4503 | + }, |
---|
| 4504 | + }, |
---|
| 4505 | + { |
---|
| 4506 | + .active_pipes = BIT(PIPE_A) | BIT(PIPE_B), |
---|
| 4507 | + .dbuf_mask = { |
---|
| 4508 | + [PIPE_A] = BIT(DBUF_S2), |
---|
| 4509 | + [PIPE_B] = BIT(DBUF_S1), |
---|
| 4510 | + }, |
---|
| 4511 | + }, |
---|
| 4512 | + { |
---|
| 4513 | + .active_pipes = BIT(PIPE_C), |
---|
| 4514 | + .dbuf_mask = { |
---|
| 4515 | + [PIPE_C] = BIT(DBUF_S2) | BIT(DBUF_S1), |
---|
| 4516 | + }, |
---|
| 4517 | + }, |
---|
| 4518 | + { |
---|
| 4519 | + .active_pipes = BIT(PIPE_A) | BIT(PIPE_C), |
---|
| 4520 | + .dbuf_mask = { |
---|
| 4521 | + [PIPE_A] = BIT(DBUF_S1), |
---|
| 4522 | + [PIPE_C] = BIT(DBUF_S2), |
---|
| 4523 | + }, |
---|
| 4524 | + }, |
---|
| 4525 | + { |
---|
| 4526 | + .active_pipes = BIT(PIPE_B) | BIT(PIPE_C), |
---|
| 4527 | + .dbuf_mask = { |
---|
| 4528 | + [PIPE_B] = BIT(DBUF_S1), |
---|
| 4529 | + [PIPE_C] = BIT(DBUF_S2), |
---|
| 4530 | + }, |
---|
| 4531 | + }, |
---|
| 4532 | + { |
---|
| 4533 | + .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), |
---|
| 4534 | + .dbuf_mask = { |
---|
| 4535 | + [PIPE_A] = BIT(DBUF_S1), |
---|
| 4536 | + [PIPE_B] = BIT(DBUF_S1), |
---|
| 4537 | + [PIPE_C] = BIT(DBUF_S2), |
---|
| 4538 | + }, |
---|
| 4539 | + }, |
---|
| 4540 | + { |
---|
| 4541 | + .active_pipes = BIT(PIPE_D), |
---|
| 4542 | + .dbuf_mask = { |
---|
| 4543 | + [PIPE_D] = BIT(DBUF_S2) | BIT(DBUF_S1), |
---|
| 4544 | + }, |
---|
| 4545 | + }, |
---|
| 4546 | + { |
---|
| 4547 | + .active_pipes = BIT(PIPE_A) | BIT(PIPE_D), |
---|
| 4548 | + .dbuf_mask = { |
---|
| 4549 | + [PIPE_A] = BIT(DBUF_S1), |
---|
| 4550 | + [PIPE_D] = BIT(DBUF_S2), |
---|
| 4551 | + }, |
---|
| 4552 | + }, |
---|
| 4553 | + { |
---|
| 4554 | + .active_pipes = BIT(PIPE_B) | BIT(PIPE_D), |
---|
| 4555 | + .dbuf_mask = { |
---|
| 4556 | + [PIPE_B] = BIT(DBUF_S1), |
---|
| 4557 | + [PIPE_D] = BIT(DBUF_S2), |
---|
| 4558 | + }, |
---|
| 4559 | + }, |
---|
| 4560 | + { |
---|
| 4561 | + .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_D), |
---|
| 4562 | + .dbuf_mask = { |
---|
| 4563 | + [PIPE_A] = BIT(DBUF_S1), |
---|
| 4564 | + [PIPE_B] = BIT(DBUF_S1), |
---|
| 4565 | + [PIPE_D] = BIT(DBUF_S2), |
---|
| 4566 | + }, |
---|
| 4567 | + }, |
---|
| 4568 | + { |
---|
| 4569 | + .active_pipes = BIT(PIPE_C) | BIT(PIPE_D), |
---|
| 4570 | + .dbuf_mask = { |
---|
| 4571 | + [PIPE_C] = BIT(DBUF_S1), |
---|
| 4572 | + [PIPE_D] = BIT(DBUF_S2), |
---|
| 4573 | + }, |
---|
| 4574 | + }, |
---|
| 4575 | + { |
---|
| 4576 | + .active_pipes = BIT(PIPE_A) | BIT(PIPE_C) | BIT(PIPE_D), |
---|
| 4577 | + .dbuf_mask = { |
---|
| 4578 | + [PIPE_A] = BIT(DBUF_S1), |
---|
| 4579 | + [PIPE_C] = BIT(DBUF_S2), |
---|
| 4580 | + [PIPE_D] = BIT(DBUF_S2), |
---|
| 4581 | + }, |
---|
| 4582 | + }, |
---|
| 4583 | + { |
---|
| 4584 | + .active_pipes = BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), |
---|
| 4585 | + .dbuf_mask = { |
---|
| 4586 | + [PIPE_B] = BIT(DBUF_S1), |
---|
| 4587 | + [PIPE_C] = BIT(DBUF_S2), |
---|
| 4588 | + [PIPE_D] = BIT(DBUF_S2), |
---|
| 4589 | + }, |
---|
| 4590 | + }, |
---|
| 4591 | + { |
---|
| 4592 | + .active_pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), |
---|
| 4593 | + .dbuf_mask = { |
---|
| 4594 | + [PIPE_A] = BIT(DBUF_S1), |
---|
| 4595 | + [PIPE_B] = BIT(DBUF_S1), |
---|
| 4596 | + [PIPE_C] = BIT(DBUF_S2), |
---|
| 4597 | + [PIPE_D] = BIT(DBUF_S2), |
---|
| 4598 | + }, |
---|
| 4599 | + }, |
---|
| 4600 | + {} |
---|
| 4601 | +}; |
---|
4102 | 4602 | |
---|
4103 | | - if (!cstate->base.enable) |
---|
4104 | | - return 0; |
---|
| 4603 | +static u8 compute_dbuf_slices(enum pipe pipe, u8 active_pipes, |
---|
| 4604 | + const struct dbuf_slice_conf_entry *dbuf_slices) |
---|
| 4605 | +{ |
---|
| 4606 | + int i; |
---|
4105 | 4607 | |
---|
4106 | | - drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { |
---|
4107 | | - uint_fixed_16_16_t plane_downscale; |
---|
4108 | | - uint_fixed_16_16_t fp_9_div_8 = div_fixed16(9, 8); |
---|
4109 | | - int bpp; |
---|
4110 | | - |
---|
4111 | | - if (!intel_wm_plane_visible(cstate, |
---|
4112 | | - to_intel_plane_state(pstate))) |
---|
4113 | | - continue; |
---|
4114 | | - |
---|
4115 | | - if (WARN_ON(!pstate->fb)) |
---|
4116 | | - return -EINVAL; |
---|
4117 | | - |
---|
4118 | | - intel_pstate = to_intel_plane_state(pstate); |
---|
4119 | | - plane_downscale = skl_plane_downscale_amount(cstate, |
---|
4120 | | - intel_pstate); |
---|
4121 | | - bpp = pstate->fb->format->cpp[0] * 8; |
---|
4122 | | - if (bpp == 64) |
---|
4123 | | - plane_downscale = mul_fixed16(plane_downscale, |
---|
4124 | | - fp_9_div_8); |
---|
4125 | | - |
---|
4126 | | - max_downscale = max_fixed16(plane_downscale, max_downscale); |
---|
| 4608 | + for (i = 0; i < dbuf_slices[i].active_pipes; i++) { |
---|
| 4609 | + if (dbuf_slices[i].active_pipes == active_pipes) |
---|
| 4610 | + return dbuf_slices[i].dbuf_mask[pipe]; |
---|
4127 | 4611 | } |
---|
4128 | | - pipe_downscale = skl_pipe_downscale_amount(cstate); |
---|
4129 | | - |
---|
4130 | | - pipe_downscale = mul_fixed16(pipe_downscale, max_downscale); |
---|
4131 | | - |
---|
4132 | | - crtc_clock = crtc_state->adjusted_mode.crtc_clock; |
---|
4133 | | - dotclk = to_intel_atomic_state(state)->cdclk.logical.cdclk; |
---|
4134 | | - |
---|
4135 | | - if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10) |
---|
4136 | | - dotclk *= 2; |
---|
4137 | | - |
---|
4138 | | - pipe_max_pixel_rate = div_round_up_u32_fixed16(dotclk, pipe_downscale); |
---|
4139 | | - |
---|
4140 | | - if (pipe_max_pixel_rate < crtc_clock) { |
---|
4141 | | - DRM_DEBUG_KMS("Max supported pixel clock with scaling exceeded\n"); |
---|
4142 | | - return -EINVAL; |
---|
4143 | | - } |
---|
4144 | | - |
---|
4145 | 4612 | return 0; |
---|
4146 | 4613 | } |
---|
4147 | 4614 | |
---|
4148 | | -static unsigned int |
---|
4149 | | -skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, |
---|
4150 | | - const struct drm_plane_state *pstate, |
---|
4151 | | - const int plane) |
---|
| 4615 | +/* |
---|
| 4616 | + * This function finds an entry with same enabled pipe configuration and |
---|
| 4617 | + * returns correspondent DBuf slice mask as stated in BSpec for particular |
---|
| 4618 | + * platform. |
---|
| 4619 | + */ |
---|
| 4620 | +static u8 icl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes) |
---|
4152 | 4621 | { |
---|
4153 | | - struct intel_plane *intel_plane = to_intel_plane(pstate->plane); |
---|
4154 | | - struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate); |
---|
4155 | | - uint32_t data_rate; |
---|
4156 | | - uint32_t width = 0, height = 0; |
---|
4157 | | - struct drm_framebuffer *fb; |
---|
4158 | | - u32 format; |
---|
| 4622 | + /* |
---|
| 4623 | + * FIXME: For ICL this is still a bit unclear as prev BSpec revision |
---|
| 4624 | + * required calculating "pipe ratio" in order to determine |
---|
| 4625 | + * if one or two slices can be used for single pipe configurations |
---|
| 4626 | + * as additional constraint to the existing table. |
---|
| 4627 | + * However based on recent info, it should be not "pipe ratio" |
---|
| 4628 | + * but rather ratio between pixel_rate and cdclk with additional |
---|
| 4629 | + * constants, so for now we are using only table until this is |
---|
| 4630 | + * clarified. Also this is the reason why crtc_state param is |
---|
| 4631 | + * still here - we will need it once those additional constraints |
---|
| 4632 | + * pop up. |
---|
| 4633 | + */ |
---|
| 4634 | + return compute_dbuf_slices(pipe, active_pipes, icl_allowed_dbufs); |
---|
| 4635 | +} |
---|
| 4636 | + |
---|
| 4637 | +static u8 tgl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes) |
---|
| 4638 | +{ |
---|
| 4639 | + return compute_dbuf_slices(pipe, active_pipes, tgl_allowed_dbufs); |
---|
| 4640 | +} |
---|
| 4641 | + |
---|
| 4642 | +static u8 skl_compute_dbuf_slices(const struct intel_crtc_state *crtc_state, |
---|
| 4643 | + u8 active_pipes) |
---|
| 4644 | +{ |
---|
| 4645 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
| 4646 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 4647 | + enum pipe pipe = crtc->pipe; |
---|
| 4648 | + |
---|
| 4649 | + if (IS_GEN(dev_priv, 12)) |
---|
| 4650 | + return tgl_compute_dbuf_slices(pipe, active_pipes); |
---|
| 4651 | + else if (IS_GEN(dev_priv, 11)) |
---|
| 4652 | + return icl_compute_dbuf_slices(pipe, active_pipes); |
---|
| 4653 | + /* |
---|
| 4654 | + * For anything else just return one slice yet. |
---|
| 4655 | + * Should be extended for other platforms. |
---|
| 4656 | + */ |
---|
| 4657 | + return active_pipes & BIT(pipe) ? BIT(DBUF_S1) : 0; |
---|
| 4658 | +} |
---|
| 4659 | + |
---|
| 4660 | +static u64 |
---|
| 4661 | +skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state, |
---|
| 4662 | + const struct intel_plane_state *plane_state, |
---|
| 4663 | + int color_plane) |
---|
| 4664 | +{ |
---|
| 4665 | + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); |
---|
| 4666 | + const struct drm_framebuffer *fb = plane_state->hw.fb; |
---|
| 4667 | + u32 data_rate; |
---|
| 4668 | + u32 width = 0, height = 0; |
---|
4159 | 4669 | uint_fixed_16_16_t down_scale_amount; |
---|
| 4670 | + u64 rate; |
---|
4160 | 4671 | |
---|
4161 | | - if (!intel_pstate->base.visible) |
---|
| 4672 | + if (!plane_state->uapi.visible) |
---|
4162 | 4673 | return 0; |
---|
4163 | 4674 | |
---|
4164 | | - fb = pstate->fb; |
---|
4165 | | - format = fb->format->format; |
---|
4166 | | - |
---|
4167 | | - if (intel_plane->id == PLANE_CURSOR) |
---|
| 4675 | + if (plane->id == PLANE_CURSOR) |
---|
4168 | 4676 | return 0; |
---|
4169 | | - if (plane == 1 && format != DRM_FORMAT_NV12) |
---|
| 4677 | + |
---|
| 4678 | + if (color_plane == 1 && |
---|
| 4679 | + !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) |
---|
4170 | 4680 | return 0; |
---|
4171 | 4681 | |
---|
4172 | 4682 | /* |
---|
.. | .. |
---|
4174 | 4684 | * the 90/270 degree plane rotation cases (to match the |
---|
4175 | 4685 | * GTT mapping), hence no need to account for rotation here. |
---|
4176 | 4686 | */ |
---|
4177 | | - width = drm_rect_width(&intel_pstate->base.src) >> 16; |
---|
4178 | | - height = drm_rect_height(&intel_pstate->base.src) >> 16; |
---|
| 4687 | + width = drm_rect_width(&plane_state->uapi.src) >> 16; |
---|
| 4688 | + height = drm_rect_height(&plane_state->uapi.src) >> 16; |
---|
4179 | 4689 | |
---|
4180 | 4690 | /* UV plane does 1/2 pixel sub-sampling */ |
---|
4181 | | - if (plane == 1 && format == DRM_FORMAT_NV12) { |
---|
| 4691 | + if (color_plane == 1) { |
---|
4182 | 4692 | width /= 2; |
---|
4183 | 4693 | height /= 2; |
---|
4184 | 4694 | } |
---|
4185 | 4695 | |
---|
4186 | | - data_rate = width * height * fb->format->cpp[plane]; |
---|
| 4696 | + data_rate = width * height; |
---|
4187 | 4697 | |
---|
4188 | | - down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate); |
---|
| 4698 | + down_scale_amount = skl_plane_downscale_amount(crtc_state, plane_state); |
---|
4189 | 4699 | |
---|
4190 | | - return mul_round_up_u32_fixed16(data_rate, down_scale_amount); |
---|
| 4700 | + rate = mul_round_up_u32_fixed16(data_rate, down_scale_amount); |
---|
| 4701 | + |
---|
| 4702 | + rate *= fb->format->cpp[color_plane]; |
---|
| 4703 | + return rate; |
---|
4191 | 4704 | } |
---|
4192 | 4705 | |
---|
4193 | | -/* |
---|
4194 | | - * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching |
---|
4195 | | - * a 8192x4096@32bpp framebuffer: |
---|
4196 | | - * 3 * 4096 * 8192 * 4 < 2^32 |
---|
4197 | | - */ |
---|
4198 | | -static unsigned int |
---|
4199 | | -skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate, |
---|
4200 | | - unsigned int *plane_data_rate, |
---|
4201 | | - unsigned int *uv_plane_data_rate) |
---|
| 4706 | +static u64 |
---|
| 4707 | +skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state, |
---|
| 4708 | + u64 *plane_data_rate, |
---|
| 4709 | + u64 *uv_plane_data_rate) |
---|
4202 | 4710 | { |
---|
4203 | | - struct drm_crtc_state *cstate = &intel_cstate->base; |
---|
4204 | | - struct drm_atomic_state *state = cstate->state; |
---|
4205 | | - struct drm_plane *plane; |
---|
4206 | | - const struct drm_plane_state *pstate; |
---|
4207 | | - unsigned int total_data_rate = 0; |
---|
4208 | | - |
---|
4209 | | - if (WARN_ON(!state)) |
---|
4210 | | - return 0; |
---|
| 4711 | + struct intel_plane *plane; |
---|
| 4712 | + const struct intel_plane_state *plane_state; |
---|
| 4713 | + u64 total_data_rate = 0; |
---|
4211 | 4714 | |
---|
4212 | 4715 | /* Calculate and cache data rate for each plane */ |
---|
4213 | | - drm_atomic_crtc_state_for_each_plane_state(plane, pstate, cstate) { |
---|
4214 | | - enum plane_id plane_id = to_intel_plane(plane)->id; |
---|
4215 | | - unsigned int rate; |
---|
| 4716 | + intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) { |
---|
| 4717 | + enum plane_id plane_id = plane->id; |
---|
| 4718 | + u64 rate; |
---|
4216 | 4719 | |
---|
4217 | 4720 | /* packed/y */ |
---|
4218 | | - rate = skl_plane_relative_data_rate(intel_cstate, |
---|
4219 | | - pstate, 0); |
---|
| 4721 | + rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0); |
---|
4220 | 4722 | plane_data_rate[plane_id] = rate; |
---|
4221 | | - |
---|
4222 | 4723 | total_data_rate += rate; |
---|
4223 | 4724 | |
---|
4224 | 4725 | /* uv-plane */ |
---|
4225 | | - rate = skl_plane_relative_data_rate(intel_cstate, |
---|
4226 | | - pstate, 1); |
---|
| 4726 | + rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1); |
---|
4227 | 4727 | uv_plane_data_rate[plane_id] = rate; |
---|
4228 | | - |
---|
4229 | 4728 | total_data_rate += rate; |
---|
4230 | 4729 | } |
---|
4231 | 4730 | |
---|
4232 | 4731 | return total_data_rate; |
---|
4233 | 4732 | } |
---|
4234 | 4733 | |
---|
4235 | | -static uint16_t |
---|
4236 | | -skl_ddb_min_alloc(const struct drm_plane_state *pstate, const int plane) |
---|
| 4734 | +static u64 |
---|
| 4735 | +icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state, |
---|
| 4736 | + u64 *plane_data_rate) |
---|
4237 | 4737 | { |
---|
4238 | | - struct drm_framebuffer *fb = pstate->fb; |
---|
4239 | | - struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate); |
---|
4240 | | - uint32_t src_w, src_h; |
---|
4241 | | - uint32_t min_scanlines = 8; |
---|
4242 | | - uint8_t plane_bpp; |
---|
| 4738 | + struct intel_plane *plane; |
---|
| 4739 | + const struct intel_plane_state *plane_state; |
---|
| 4740 | + u64 total_data_rate = 0; |
---|
4243 | 4741 | |
---|
4244 | | - if (WARN_ON(!fb)) |
---|
4245 | | - return 0; |
---|
| 4742 | + /* Calculate and cache data rate for each plane */ |
---|
| 4743 | + intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) { |
---|
| 4744 | + enum plane_id plane_id = plane->id; |
---|
| 4745 | + u64 rate; |
---|
4246 | 4746 | |
---|
4247 | | - /* For packed formats, and uv-plane, return 0 */ |
---|
4248 | | - if (plane == 1 && fb->format->format != DRM_FORMAT_NV12) |
---|
4249 | | - return 0; |
---|
| 4747 | + if (!plane_state->planar_linked_plane) { |
---|
| 4748 | + rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0); |
---|
| 4749 | + plane_data_rate[plane_id] = rate; |
---|
| 4750 | + total_data_rate += rate; |
---|
| 4751 | + } else { |
---|
| 4752 | + enum plane_id y_plane_id; |
---|
4250 | 4753 | |
---|
4251 | | - /* For Non Y-tile return 8-blocks */ |
---|
4252 | | - if (fb->modifier != I915_FORMAT_MOD_Y_TILED && |
---|
4253 | | - fb->modifier != I915_FORMAT_MOD_Yf_TILED && |
---|
4254 | | - fb->modifier != I915_FORMAT_MOD_Y_TILED_CCS && |
---|
4255 | | - fb->modifier != I915_FORMAT_MOD_Yf_TILED_CCS) |
---|
4256 | | - return 8; |
---|
| 4754 | + /* |
---|
| 4755 | + * The slave plane might not iterate in |
---|
| 4756 | + * intel_atomic_crtc_state_for_each_plane_state(), |
---|
| 4757 | + * and needs the master plane state which may be |
---|
| 4758 | + * NULL if we try get_new_plane_state(), so we |
---|
| 4759 | + * always calculate from the master. |
---|
| 4760 | + */ |
---|
| 4761 | + if (plane_state->planar_slave) |
---|
| 4762 | + continue; |
---|
4257 | 4763 | |
---|
4258 | | - /* |
---|
4259 | | - * Src coordinates are already rotated by 270 degrees for |
---|
4260 | | - * the 90/270 degree plane rotation cases (to match the |
---|
4261 | | - * GTT mapping), hence no need to account for rotation here. |
---|
4262 | | - */ |
---|
4263 | | - src_w = drm_rect_width(&intel_pstate->base.src) >> 16; |
---|
4264 | | - src_h = drm_rect_height(&intel_pstate->base.src) >> 16; |
---|
| 4764 | + /* Y plane rate is calculated on the slave */ |
---|
| 4765 | + rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0); |
---|
| 4766 | + y_plane_id = plane_state->planar_linked_plane->id; |
---|
| 4767 | + plane_data_rate[y_plane_id] = rate; |
---|
| 4768 | + total_data_rate += rate; |
---|
4265 | 4769 | |
---|
4266 | | - /* Halve UV plane width and height for NV12 */ |
---|
4267 | | - if (plane == 1) { |
---|
4268 | | - src_w /= 2; |
---|
4269 | | - src_h /= 2; |
---|
4270 | | - } |
---|
4271 | | - |
---|
4272 | | - plane_bpp = fb->format->cpp[plane]; |
---|
4273 | | - |
---|
4274 | | - if (drm_rotation_90_or_270(pstate->rotation)) { |
---|
4275 | | - switch (plane_bpp) { |
---|
4276 | | - case 1: |
---|
4277 | | - min_scanlines = 32; |
---|
4278 | | - break; |
---|
4279 | | - case 2: |
---|
4280 | | - min_scanlines = 16; |
---|
4281 | | - break; |
---|
4282 | | - case 4: |
---|
4283 | | - min_scanlines = 8; |
---|
4284 | | - break; |
---|
4285 | | - case 8: |
---|
4286 | | - min_scanlines = 4; |
---|
4287 | | - break; |
---|
4288 | | - default: |
---|
4289 | | - WARN(1, "Unsupported pixel depth %u for rotation", |
---|
4290 | | - plane_bpp); |
---|
4291 | | - min_scanlines = 32; |
---|
| 4770 | + rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1); |
---|
| 4771 | + plane_data_rate[plane_id] = rate; |
---|
| 4772 | + total_data_rate += rate; |
---|
4292 | 4773 | } |
---|
4293 | 4774 | } |
---|
4294 | 4775 | |
---|
4295 | | - return DIV_ROUND_UP((4 * src_w * plane_bpp), 512) * min_scanlines/4 + 3; |
---|
| 4776 | + return total_data_rate; |
---|
4296 | 4777 | } |
---|
4297 | 4778 | |
---|
4298 | | -static void |
---|
4299 | | -skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active, |
---|
4300 | | - uint16_t *minimum, uint16_t *uv_minimum) |
---|
| 4779 | +static const struct skl_wm_level * |
---|
| 4780 | +skl_plane_wm_level(const struct intel_crtc_state *crtc_state, |
---|
| 4781 | + enum plane_id plane_id, |
---|
| 4782 | + int level) |
---|
4301 | 4783 | { |
---|
4302 | | - const struct drm_plane_state *pstate; |
---|
4303 | | - struct drm_plane *plane; |
---|
| 4784 | + const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal; |
---|
| 4785 | + const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id]; |
---|
4304 | 4786 | |
---|
4305 | | - drm_atomic_crtc_state_for_each_plane_state(plane, pstate, &cstate->base) { |
---|
4306 | | - enum plane_id plane_id = to_intel_plane(plane)->id; |
---|
| 4787 | + if (level == 0 && pipe_wm->use_sagv_wm) |
---|
| 4788 | + return &wm->sagv_wm0; |
---|
4307 | 4789 | |
---|
4308 | | - if (plane_id == PLANE_CURSOR) |
---|
4309 | | - continue; |
---|
4310 | | - |
---|
4311 | | - if (!pstate->visible) |
---|
4312 | | - continue; |
---|
4313 | | - |
---|
4314 | | - minimum[plane_id] = skl_ddb_min_alloc(pstate, 0); |
---|
4315 | | - uv_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1); |
---|
4316 | | - } |
---|
4317 | | - |
---|
4318 | | - minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active); |
---|
| 4790 | + return &wm->wm[level]; |
---|
4319 | 4791 | } |
---|
4320 | 4792 | |
---|
4321 | 4793 | static int |
---|
4322 | | -skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, |
---|
4323 | | - struct skl_ddb_allocation *ddb /* out */) |
---|
| 4794 | +skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state) |
---|
4324 | 4795 | { |
---|
4325 | | - struct drm_atomic_state *state = cstate->base.state; |
---|
4326 | | - struct drm_crtc *crtc = cstate->base.crtc; |
---|
4327 | | - struct drm_device *dev = crtc->dev; |
---|
4328 | | - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
---|
4329 | | - enum pipe pipe = intel_crtc->pipe; |
---|
4330 | | - struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb; |
---|
4331 | | - uint16_t alloc_size, start; |
---|
4332 | | - uint16_t minimum[I915_MAX_PLANES] = {}; |
---|
4333 | | - uint16_t uv_minimum[I915_MAX_PLANES] = {}; |
---|
4334 | | - unsigned int total_data_rate; |
---|
| 4796 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
| 4797 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 4798 | + struct skl_ddb_entry *alloc = &crtc_state->wm.skl.ddb; |
---|
| 4799 | + u16 alloc_size, start = 0; |
---|
| 4800 | + u16 total[I915_MAX_PLANES] = {}; |
---|
| 4801 | + u16 uv_total[I915_MAX_PLANES] = {}; |
---|
| 4802 | + u64 total_data_rate; |
---|
4335 | 4803 | enum plane_id plane_id; |
---|
4336 | 4804 | int num_active; |
---|
4337 | | - unsigned int plane_data_rate[I915_MAX_PLANES] = {}; |
---|
4338 | | - unsigned int uv_plane_data_rate[I915_MAX_PLANES] = {}; |
---|
4339 | | - uint16_t total_min_blocks = 0; |
---|
| 4805 | + u64 plane_data_rate[I915_MAX_PLANES] = {}; |
---|
| 4806 | + u64 uv_plane_data_rate[I915_MAX_PLANES] = {}; |
---|
| 4807 | + u32 blocks; |
---|
| 4808 | + int level; |
---|
| 4809 | + int ret; |
---|
4340 | 4810 | |
---|
4341 | 4811 | /* Clear the partitioning for disabled planes. */ |
---|
4342 | | - memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); |
---|
4343 | | - memset(ddb->uv_plane[pipe], 0, sizeof(ddb->uv_plane[pipe])); |
---|
| 4812 | + memset(crtc_state->wm.skl.plane_ddb_y, 0, sizeof(crtc_state->wm.skl.plane_ddb_y)); |
---|
| 4813 | + memset(crtc_state->wm.skl.plane_ddb_uv, 0, sizeof(crtc_state->wm.skl.plane_ddb_uv)); |
---|
4344 | 4814 | |
---|
4345 | | - if (WARN_ON(!state)) |
---|
4346 | | - return 0; |
---|
| 4815 | + if (!crtc_state->hw.active) { |
---|
| 4816 | + struct intel_atomic_state *state = |
---|
| 4817 | + to_intel_atomic_state(crtc_state->uapi.state); |
---|
| 4818 | + struct intel_dbuf_state *new_dbuf_state = |
---|
| 4819 | + intel_atomic_get_new_dbuf_state(state); |
---|
| 4820 | + const struct intel_dbuf_state *old_dbuf_state = |
---|
| 4821 | + intel_atomic_get_old_dbuf_state(state); |
---|
4347 | 4822 | |
---|
4348 | | - if (!cstate->base.active) { |
---|
| 4823 | + /* |
---|
| 4824 | + * FIXME hack to make sure we compute this sensibly when |
---|
| 4825 | + * turning off all the pipes. Otherwise we leave it at |
---|
| 4826 | + * whatever we had previously, and then runtime PM will |
---|
| 4827 | + * mess it up by turning off all but S1. Remove this |
---|
| 4828 | + * once the dbuf state computation flow becomes sane. |
---|
| 4829 | + */ |
---|
| 4830 | + if (new_dbuf_state->active_pipes == 0) { |
---|
| 4831 | + new_dbuf_state->enabled_slices = BIT(DBUF_S1); |
---|
| 4832 | + |
---|
| 4833 | + if (old_dbuf_state->enabled_slices != new_dbuf_state->enabled_slices) { |
---|
| 4834 | + ret = intel_atomic_serialize_global_state(&new_dbuf_state->base); |
---|
| 4835 | + if (ret) |
---|
| 4836 | + return ret; |
---|
| 4837 | + } |
---|
| 4838 | + } |
---|
| 4839 | + |
---|
4349 | 4840 | alloc->start = alloc->end = 0; |
---|
4350 | 4841 | return 0; |
---|
4351 | 4842 | } |
---|
4352 | 4843 | |
---|
4353 | | - total_data_rate = skl_get_total_relative_data_rate(cstate, |
---|
4354 | | - plane_data_rate, |
---|
4355 | | - uv_plane_data_rate); |
---|
4356 | | - skl_ddb_get_pipe_allocation_limits(dev, cstate, total_data_rate, ddb, |
---|
4357 | | - alloc, &num_active); |
---|
| 4844 | + if (INTEL_GEN(dev_priv) >= 11) |
---|
| 4845 | + total_data_rate = |
---|
| 4846 | + icl_get_total_relative_data_rate(crtc_state, |
---|
| 4847 | + plane_data_rate); |
---|
| 4848 | + else |
---|
| 4849 | + total_data_rate = |
---|
| 4850 | + skl_get_total_relative_data_rate(crtc_state, |
---|
| 4851 | + plane_data_rate, |
---|
| 4852 | + uv_plane_data_rate); |
---|
| 4853 | + |
---|
| 4854 | + ret = skl_ddb_get_pipe_allocation_limits(dev_priv, crtc_state, |
---|
| 4855 | + total_data_rate, |
---|
| 4856 | + alloc, &num_active); |
---|
| 4857 | + if (ret) |
---|
| 4858 | + return ret; |
---|
| 4859 | + |
---|
4358 | 4860 | alloc_size = skl_ddb_entry_size(alloc); |
---|
4359 | 4861 | if (alloc_size == 0) |
---|
4360 | 4862 | return 0; |
---|
4361 | 4863 | |
---|
4362 | | - skl_ddb_calc_min(cstate, num_active, minimum, uv_minimum); |
---|
| 4864 | + /* Allocate fixed number of blocks for cursor. */ |
---|
| 4865 | + total[PLANE_CURSOR] = skl_cursor_allocation(crtc_state, num_active); |
---|
| 4866 | + alloc_size -= total[PLANE_CURSOR]; |
---|
| 4867 | + crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR].start = |
---|
| 4868 | + alloc->end - total[PLANE_CURSOR]; |
---|
| 4869 | + crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR].end = alloc->end; |
---|
4363 | 4870 | |
---|
4364 | | - /* |
---|
4365 | | - * 1. Allocate the mininum required blocks for each active plane |
---|
4366 | | - * and allocate the cursor, it doesn't require extra allocation |
---|
4367 | | - * proportional to the data rate. |
---|
4368 | | - */ |
---|
4369 | | - |
---|
4370 | | - for_each_plane_id_on_crtc(intel_crtc, plane_id) { |
---|
4371 | | - total_min_blocks += minimum[plane_id]; |
---|
4372 | | - total_min_blocks += uv_minimum[plane_id]; |
---|
4373 | | - } |
---|
4374 | | - |
---|
4375 | | - if (total_min_blocks > alloc_size) { |
---|
4376 | | - DRM_DEBUG_KMS("Requested display configuration exceeds system DDB limitations"); |
---|
4377 | | - DRM_DEBUG_KMS("minimum required %d/%d\n", total_min_blocks, |
---|
4378 | | - alloc_size); |
---|
4379 | | - return -EINVAL; |
---|
4380 | | - } |
---|
4381 | | - |
---|
4382 | | - alloc_size -= total_min_blocks; |
---|
4383 | | - ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR]; |
---|
4384 | | - ddb->plane[pipe][PLANE_CURSOR].end = alloc->end; |
---|
4385 | | - |
---|
4386 | | - /* |
---|
4387 | | - * 2. Distribute the remaining space in proportion to the amount of |
---|
4388 | | - * data each plane needs to fetch from memory. |
---|
4389 | | - * |
---|
4390 | | - * FIXME: we may not allocate every single block here. |
---|
4391 | | - */ |
---|
4392 | 4871 | if (total_data_rate == 0) |
---|
4393 | 4872 | return 0; |
---|
4394 | 4873 | |
---|
4395 | | - start = alloc->start; |
---|
4396 | | - for_each_plane_id_on_crtc(intel_crtc, plane_id) { |
---|
4397 | | - unsigned int data_rate, uv_data_rate; |
---|
4398 | | - uint16_t plane_blocks, uv_plane_blocks; |
---|
| 4874 | + /* |
---|
| 4875 | + * Find the highest watermark level for which we can satisfy the block |
---|
| 4876 | + * requirement of active planes. |
---|
| 4877 | + */ |
---|
| 4878 | + for (level = ilk_wm_max_level(dev_priv); level >= 0; level--) { |
---|
| 4879 | + blocks = 0; |
---|
| 4880 | + for_each_plane_id_on_crtc(crtc, plane_id) { |
---|
| 4881 | + const struct skl_plane_wm *wm = |
---|
| 4882 | + &crtc_state->wm.skl.optimal.planes[plane_id]; |
---|
| 4883 | + |
---|
| 4884 | + if (plane_id == PLANE_CURSOR) { |
---|
| 4885 | + if (wm->wm[level].min_ddb_alloc > total[PLANE_CURSOR]) { |
---|
| 4886 | + drm_WARN_ON(&dev_priv->drm, |
---|
| 4887 | + wm->wm[level].min_ddb_alloc != U16_MAX); |
---|
| 4888 | + blocks = U32_MAX; |
---|
| 4889 | + break; |
---|
| 4890 | + } |
---|
| 4891 | + continue; |
---|
| 4892 | + } |
---|
| 4893 | + |
---|
| 4894 | + blocks += wm->wm[level].min_ddb_alloc; |
---|
| 4895 | + blocks += wm->uv_wm[level].min_ddb_alloc; |
---|
| 4896 | + } |
---|
| 4897 | + |
---|
| 4898 | + if (blocks <= alloc_size) { |
---|
| 4899 | + alloc_size -= blocks; |
---|
| 4900 | + break; |
---|
| 4901 | + } |
---|
| 4902 | + } |
---|
| 4903 | + |
---|
| 4904 | + if (level < 0) { |
---|
| 4905 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 4906 | + "Requested display configuration exceeds system DDB limitations"); |
---|
| 4907 | + drm_dbg_kms(&dev_priv->drm, "minimum required %d/%d\n", |
---|
| 4908 | + blocks, alloc_size); |
---|
| 4909 | + return -EINVAL; |
---|
| 4910 | + } |
---|
| 4911 | + |
---|
| 4912 | + /* |
---|
| 4913 | + * Grant each plane the blocks it requires at the highest achievable |
---|
| 4914 | + * watermark level, plus an extra share of the leftover blocks |
---|
| 4915 | + * proportional to its relative data rate. |
---|
| 4916 | + */ |
---|
| 4917 | + for_each_plane_id_on_crtc(crtc, plane_id) { |
---|
| 4918 | + const struct skl_plane_wm *wm = |
---|
| 4919 | + &crtc_state->wm.skl.optimal.planes[plane_id]; |
---|
| 4920 | + u64 rate; |
---|
| 4921 | + u16 extra; |
---|
4399 | 4922 | |
---|
4400 | 4923 | if (plane_id == PLANE_CURSOR) |
---|
4401 | 4924 | continue; |
---|
4402 | 4925 | |
---|
4403 | | - data_rate = plane_data_rate[plane_id]; |
---|
4404 | | - |
---|
4405 | 4926 | /* |
---|
4406 | | - * allocation for (packed formats) or (uv-plane part of planar format): |
---|
4407 | | - * promote the expression to 64 bits to avoid overflowing, the |
---|
4408 | | - * result is < available as data_rate / total_data_rate < 1 |
---|
| 4927 | + * We've accounted for all active planes; remaining planes are |
---|
| 4928 | + * all disabled. |
---|
4409 | 4929 | */ |
---|
4410 | | - plane_blocks = minimum[plane_id]; |
---|
4411 | | - plane_blocks += div_u64((uint64_t)alloc_size * data_rate, |
---|
4412 | | - total_data_rate); |
---|
| 4930 | + if (total_data_rate == 0) |
---|
| 4931 | + break; |
---|
| 4932 | + |
---|
| 4933 | + rate = plane_data_rate[plane_id]; |
---|
| 4934 | + extra = min_t(u16, alloc_size, |
---|
| 4935 | + DIV64_U64_ROUND_UP(alloc_size * rate, |
---|
| 4936 | + total_data_rate)); |
---|
| 4937 | + total[plane_id] = wm->wm[level].min_ddb_alloc + extra; |
---|
| 4938 | + alloc_size -= extra; |
---|
| 4939 | + total_data_rate -= rate; |
---|
| 4940 | + |
---|
| 4941 | + if (total_data_rate == 0) |
---|
| 4942 | + break; |
---|
| 4943 | + |
---|
| 4944 | + rate = uv_plane_data_rate[plane_id]; |
---|
| 4945 | + extra = min_t(u16, alloc_size, |
---|
| 4946 | + DIV64_U64_ROUND_UP(alloc_size * rate, |
---|
| 4947 | + total_data_rate)); |
---|
| 4948 | + uv_total[plane_id] = wm->uv_wm[level].min_ddb_alloc + extra; |
---|
| 4949 | + alloc_size -= extra; |
---|
| 4950 | + total_data_rate -= rate; |
---|
| 4951 | + } |
---|
| 4952 | + drm_WARN_ON(&dev_priv->drm, alloc_size != 0 || total_data_rate != 0); |
---|
| 4953 | + |
---|
| 4954 | + /* Set the actual DDB start/end points for each plane */ |
---|
| 4955 | + start = alloc->start; |
---|
| 4956 | + for_each_plane_id_on_crtc(crtc, plane_id) { |
---|
| 4957 | + struct skl_ddb_entry *plane_alloc = |
---|
| 4958 | + &crtc_state->wm.skl.plane_ddb_y[plane_id]; |
---|
| 4959 | + struct skl_ddb_entry *uv_plane_alloc = |
---|
| 4960 | + &crtc_state->wm.skl.plane_ddb_uv[plane_id]; |
---|
| 4961 | + |
---|
| 4962 | + if (plane_id == PLANE_CURSOR) |
---|
| 4963 | + continue; |
---|
| 4964 | + |
---|
| 4965 | + /* Gen11+ uses a separate plane for UV watermarks */ |
---|
| 4966 | + drm_WARN_ON(&dev_priv->drm, |
---|
| 4967 | + INTEL_GEN(dev_priv) >= 11 && uv_total[plane_id]); |
---|
4413 | 4968 | |
---|
4414 | 4969 | /* Leave disabled planes at (0,0) */ |
---|
4415 | | - if (data_rate) { |
---|
4416 | | - ddb->plane[pipe][plane_id].start = start; |
---|
4417 | | - ddb->plane[pipe][plane_id].end = start + plane_blocks; |
---|
| 4970 | + if (total[plane_id]) { |
---|
| 4971 | + plane_alloc->start = start; |
---|
| 4972 | + start += total[plane_id]; |
---|
| 4973 | + plane_alloc->end = start; |
---|
4418 | 4974 | } |
---|
4419 | 4975 | |
---|
4420 | | - start += plane_blocks; |
---|
4421 | | - |
---|
4422 | | - /* Allocate DDB for UV plane for planar format/NV12 */ |
---|
4423 | | - uv_data_rate = uv_plane_data_rate[plane_id]; |
---|
4424 | | - |
---|
4425 | | - uv_plane_blocks = uv_minimum[plane_id]; |
---|
4426 | | - uv_plane_blocks += div_u64((uint64_t)alloc_size * uv_data_rate, |
---|
4427 | | - total_data_rate); |
---|
4428 | | - |
---|
4429 | | - if (uv_data_rate) { |
---|
4430 | | - ddb->uv_plane[pipe][plane_id].start = start; |
---|
4431 | | - ddb->uv_plane[pipe][plane_id].end = |
---|
4432 | | - start + uv_plane_blocks; |
---|
| 4976 | + if (uv_total[plane_id]) { |
---|
| 4977 | + uv_plane_alloc->start = start; |
---|
| 4978 | + start += uv_total[plane_id]; |
---|
| 4979 | + uv_plane_alloc->end = start; |
---|
4433 | 4980 | } |
---|
| 4981 | + } |
---|
4434 | 4982 | |
---|
4435 | | - start += uv_plane_blocks; |
---|
| 4983 | + /* |
---|
| 4984 | + * When we calculated watermark values we didn't know how high |
---|
| 4985 | + * of a level we'd actually be able to hit, so we just marked |
---|
| 4986 | + * all levels as "enabled." Go back now and disable the ones |
---|
| 4987 | + * that aren't actually possible. |
---|
| 4988 | + */ |
---|
| 4989 | + for (level++; level <= ilk_wm_max_level(dev_priv); level++) { |
---|
| 4990 | + for_each_plane_id_on_crtc(crtc, plane_id) { |
---|
| 4991 | + struct skl_plane_wm *wm = |
---|
| 4992 | + &crtc_state->wm.skl.optimal.planes[plane_id]; |
---|
| 4993 | + |
---|
| 4994 | + /* |
---|
| 4995 | + * We only disable the watermarks for each plane if |
---|
| 4996 | + * they exceed the ddb allocation of said plane. This |
---|
| 4997 | + * is done so that we don't end up touching cursor |
---|
| 4998 | + * watermarks needlessly when some other plane reduces |
---|
| 4999 | + * our max possible watermark level. |
---|
| 5000 | + * |
---|
| 5001 | + * Bspec has this to say about the PLANE_WM enable bit: |
---|
| 5002 | + * "All the watermarks at this level for all enabled |
---|
| 5003 | + * planes must be enabled before the level will be used." |
---|
| 5004 | + * So this is actually safe to do. |
---|
| 5005 | + */ |
---|
| 5006 | + if (wm->wm[level].min_ddb_alloc > total[plane_id] || |
---|
| 5007 | + wm->uv_wm[level].min_ddb_alloc > uv_total[plane_id]) |
---|
| 5008 | + memset(&wm->wm[level], 0, sizeof(wm->wm[level])); |
---|
| 5009 | + |
---|
| 5010 | + /* |
---|
| 5011 | + * Wa_1408961008:icl, ehl |
---|
| 5012 | + * Underruns with WM1+ disabled |
---|
| 5013 | + */ |
---|
| 5014 | + if (IS_GEN(dev_priv, 11) && |
---|
| 5015 | + level == 1 && wm->wm[0].plane_en) { |
---|
| 5016 | + wm->wm[level].plane_res_b = wm->wm[0].plane_res_b; |
---|
| 5017 | + wm->wm[level].plane_res_l = wm->wm[0].plane_res_l; |
---|
| 5018 | + wm->wm[level].ignore_lines = wm->wm[0].ignore_lines; |
---|
| 5019 | + } |
---|
| 5020 | + } |
---|
| 5021 | + } |
---|
| 5022 | + |
---|
| 5023 | + /* |
---|
| 5024 | + * Go back and disable the transition watermark if it turns out we |
---|
| 5025 | + * don't have enough DDB blocks for it. |
---|
| 5026 | + */ |
---|
| 5027 | + for_each_plane_id_on_crtc(crtc, plane_id) { |
---|
| 5028 | + struct skl_plane_wm *wm = |
---|
| 5029 | + &crtc_state->wm.skl.optimal.planes[plane_id]; |
---|
| 5030 | + |
---|
| 5031 | + if (wm->trans_wm.plane_res_b >= total[plane_id]) |
---|
| 5032 | + memset(&wm->trans_wm, 0, sizeof(wm->trans_wm)); |
---|
4436 | 5033 | } |
---|
4437 | 5034 | |
---|
4438 | 5035 | return 0; |
---|
.. | .. |
---|
4445 | 5042 | * 2xcdclk is 1350 MHz and the pixel rate should never exceed that. |
---|
4446 | 5043 | */ |
---|
4447 | 5044 | static uint_fixed_16_16_t |
---|
4448 | | -skl_wm_method1(const struct drm_i915_private *dev_priv, uint32_t pixel_rate, |
---|
4449 | | - uint8_t cpp, uint32_t latency, uint32_t dbuf_block_size) |
---|
| 5045 | +skl_wm_method1(const struct drm_i915_private *dev_priv, u32 pixel_rate, |
---|
| 5046 | + u8 cpp, u32 latency, u32 dbuf_block_size) |
---|
4450 | 5047 | { |
---|
4451 | | - uint32_t wm_intermediate_val; |
---|
| 5048 | + u32 wm_intermediate_val; |
---|
4452 | 5049 | uint_fixed_16_16_t ret; |
---|
4453 | 5050 | |
---|
4454 | 5051 | if (latency == 0) |
---|
.. | .. |
---|
4457 | 5054 | wm_intermediate_val = latency * pixel_rate * cpp; |
---|
4458 | 5055 | ret = div_fixed16(wm_intermediate_val, 1000 * dbuf_block_size); |
---|
4459 | 5056 | |
---|
4460 | | - if (INTEL_GEN(dev_priv) >= 10) |
---|
| 5057 | + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) |
---|
4461 | 5058 | ret = add_fixed16_u32(ret, 1); |
---|
4462 | 5059 | |
---|
4463 | 5060 | return ret; |
---|
4464 | 5061 | } |
---|
4465 | 5062 | |
---|
4466 | | -static uint_fixed_16_16_t skl_wm_method2(uint32_t pixel_rate, |
---|
4467 | | - uint32_t pipe_htotal, |
---|
4468 | | - uint32_t latency, |
---|
4469 | | - uint_fixed_16_16_t plane_blocks_per_line) |
---|
| 5063 | +static uint_fixed_16_16_t |
---|
| 5064 | +skl_wm_method2(u32 pixel_rate, u32 pipe_htotal, u32 latency, |
---|
| 5065 | + uint_fixed_16_16_t plane_blocks_per_line) |
---|
4470 | 5066 | { |
---|
4471 | | - uint32_t wm_intermediate_val; |
---|
| 5067 | + u32 wm_intermediate_val; |
---|
4472 | 5068 | uint_fixed_16_16_t ret; |
---|
4473 | 5069 | |
---|
4474 | 5070 | if (latency == 0) |
---|
.. | .. |
---|
4482 | 5078 | } |
---|
4483 | 5079 | |
---|
4484 | 5080 | static uint_fixed_16_16_t |
---|
4485 | | -intel_get_linetime_us(struct intel_crtc_state *cstate) |
---|
| 5081 | +intel_get_linetime_us(const struct intel_crtc_state *crtc_state) |
---|
4486 | 5082 | { |
---|
4487 | | - uint32_t pixel_rate; |
---|
4488 | | - uint32_t crtc_htotal; |
---|
| 5083 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
| 5084 | + u32 pixel_rate; |
---|
| 5085 | + u32 crtc_htotal; |
---|
4489 | 5086 | uint_fixed_16_16_t linetime_us; |
---|
4490 | 5087 | |
---|
4491 | | - if (!cstate->base.active) |
---|
| 5088 | + if (!crtc_state->hw.active) |
---|
4492 | 5089 | return u32_to_fixed16(0); |
---|
4493 | 5090 | |
---|
4494 | | - pixel_rate = cstate->pixel_rate; |
---|
| 5091 | + pixel_rate = crtc_state->pixel_rate; |
---|
4495 | 5092 | |
---|
4496 | | - if (WARN_ON(pixel_rate == 0)) |
---|
| 5093 | + if (drm_WARN_ON(&dev_priv->drm, pixel_rate == 0)) |
---|
4497 | 5094 | return u32_to_fixed16(0); |
---|
4498 | 5095 | |
---|
4499 | | - crtc_htotal = cstate->base.adjusted_mode.crtc_htotal; |
---|
| 5096 | + crtc_htotal = crtc_state->hw.adjusted_mode.crtc_htotal; |
---|
4500 | 5097 | linetime_us = div_fixed16(crtc_htotal * 1000, pixel_rate); |
---|
4501 | 5098 | |
---|
4502 | 5099 | return linetime_us; |
---|
4503 | 5100 | } |
---|
4504 | 5101 | |
---|
4505 | | -static uint32_t |
---|
4506 | | -skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *cstate, |
---|
4507 | | - const struct intel_plane_state *pstate) |
---|
| 5102 | +static u32 |
---|
| 5103 | +skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *crtc_state, |
---|
| 5104 | + const struct intel_plane_state *plane_state) |
---|
4508 | 5105 | { |
---|
4509 | | - uint64_t adjusted_pixel_rate; |
---|
| 5106 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
| 5107 | + u64 adjusted_pixel_rate; |
---|
4510 | 5108 | uint_fixed_16_16_t downscale_amount; |
---|
4511 | 5109 | |
---|
4512 | 5110 | /* Shouldn't reach here on disabled planes... */ |
---|
4513 | | - if (WARN_ON(!intel_wm_plane_visible(cstate, pstate))) |
---|
| 5111 | + if (drm_WARN_ON(&dev_priv->drm, |
---|
| 5112 | + !intel_wm_plane_visible(crtc_state, plane_state))) |
---|
4514 | 5113 | return 0; |
---|
4515 | 5114 | |
---|
4516 | 5115 | /* |
---|
4517 | 5116 | * Adjusted plane pixel rate is just the pipe's adjusted pixel rate |
---|
4518 | 5117 | * with additional adjustments for plane-specific scaling. |
---|
4519 | 5118 | */ |
---|
4520 | | - adjusted_pixel_rate = cstate->pixel_rate; |
---|
4521 | | - downscale_amount = skl_plane_downscale_amount(cstate, pstate); |
---|
| 5119 | + adjusted_pixel_rate = crtc_state->pixel_rate; |
---|
| 5120 | + downscale_amount = skl_plane_downscale_amount(crtc_state, plane_state); |
---|
4522 | 5121 | |
---|
4523 | 5122 | return mul_round_up_u32_fixed16(adjusted_pixel_rate, |
---|
4524 | 5123 | downscale_amount); |
---|
4525 | 5124 | } |
---|
4526 | 5125 | |
---|
4527 | 5126 | static int |
---|
4528 | | -skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv, |
---|
4529 | | - struct intel_crtc_state *cstate, |
---|
4530 | | - const struct intel_plane_state *intel_pstate, |
---|
4531 | | - struct skl_wm_params *wp, int plane_id) |
---|
| 5127 | +skl_compute_wm_params(const struct intel_crtc_state *crtc_state, |
---|
| 5128 | + int width, const struct drm_format_info *format, |
---|
| 5129 | + u64 modifier, unsigned int rotation, |
---|
| 5130 | + u32 plane_pixel_rate, struct skl_wm_params *wp, |
---|
| 5131 | + int color_plane) |
---|
4532 | 5132 | { |
---|
4533 | | - struct intel_plane *plane = to_intel_plane(intel_pstate->base.plane); |
---|
4534 | | - const struct drm_plane_state *pstate = &intel_pstate->base; |
---|
4535 | | - const struct drm_framebuffer *fb = pstate->fb; |
---|
4536 | | - uint32_t interm_pbpl; |
---|
4537 | | - struct intel_atomic_state *state = |
---|
4538 | | - to_intel_atomic_state(cstate->base.state); |
---|
4539 | | - bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state); |
---|
| 5133 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
| 5134 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 5135 | + u32 interm_pbpl; |
---|
4540 | 5136 | |
---|
4541 | | - if (!intel_wm_plane_visible(cstate, intel_pstate)) |
---|
4542 | | - return 0; |
---|
4543 | | - |
---|
4544 | | - /* only NV12 format has two planes */ |
---|
4545 | | - if (plane_id == 1 && fb->format->format != DRM_FORMAT_NV12) { |
---|
4546 | | - DRM_DEBUG_KMS("Non NV12 format have single plane\n"); |
---|
| 5137 | + /* only planar format has two planes */ |
---|
| 5138 | + if (color_plane == 1 && |
---|
| 5139 | + !intel_format_info_is_yuv_semiplanar(format, modifier)) { |
---|
| 5140 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 5141 | + "Non planar format have single plane\n"); |
---|
4547 | 5142 | return -EINVAL; |
---|
4548 | 5143 | } |
---|
4549 | 5144 | |
---|
4550 | | - wp->y_tiled = fb->modifier == I915_FORMAT_MOD_Y_TILED || |
---|
4551 | | - fb->modifier == I915_FORMAT_MOD_Yf_TILED || |
---|
4552 | | - fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || |
---|
4553 | | - fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS; |
---|
4554 | | - wp->x_tiled = fb->modifier == I915_FORMAT_MOD_X_TILED; |
---|
4555 | | - wp->rc_surface = fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || |
---|
4556 | | - fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS; |
---|
4557 | | - wp->is_planar = fb->format->format == DRM_FORMAT_NV12; |
---|
| 5145 | + wp->y_tiled = modifier == I915_FORMAT_MOD_Y_TILED || |
---|
| 5146 | + modifier == I915_FORMAT_MOD_Yf_TILED || |
---|
| 5147 | + modifier == I915_FORMAT_MOD_Y_TILED_CCS || |
---|
| 5148 | + modifier == I915_FORMAT_MOD_Yf_TILED_CCS || |
---|
| 5149 | + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || |
---|
| 5150 | + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS; |
---|
| 5151 | + wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED; |
---|
| 5152 | + wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS || |
---|
| 5153 | + modifier == I915_FORMAT_MOD_Yf_TILED_CCS || |
---|
| 5154 | + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || |
---|
| 5155 | + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS; |
---|
| 5156 | + wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier); |
---|
4558 | 5157 | |
---|
4559 | | - if (plane->id == PLANE_CURSOR) { |
---|
4560 | | - wp->width = intel_pstate->base.crtc_w; |
---|
4561 | | - } else { |
---|
4562 | | - /* |
---|
4563 | | - * Src coordinates are already rotated by 270 degrees for |
---|
4564 | | - * the 90/270 degree plane rotation cases (to match the |
---|
4565 | | - * GTT mapping), hence no need to account for rotation here. |
---|
4566 | | - */ |
---|
4567 | | - wp->width = drm_rect_width(&intel_pstate->base.src) >> 16; |
---|
4568 | | - } |
---|
4569 | | - |
---|
4570 | | - if (plane_id == 1 && wp->is_planar) |
---|
| 5158 | + wp->width = width; |
---|
| 5159 | + if (color_plane == 1 && wp->is_planar) |
---|
4571 | 5160 | wp->width /= 2; |
---|
4572 | 5161 | |
---|
4573 | | - wp->cpp = fb->format->cpp[plane_id]; |
---|
4574 | | - wp->plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, |
---|
4575 | | - intel_pstate); |
---|
| 5162 | + wp->cpp = format->cpp[color_plane]; |
---|
| 5163 | + wp->plane_pixel_rate = plane_pixel_rate; |
---|
4576 | 5164 | |
---|
4577 | 5165 | if (INTEL_GEN(dev_priv) >= 11 && |
---|
4578 | | - fb->modifier == I915_FORMAT_MOD_Yf_TILED && wp->cpp == 8) |
---|
| 5166 | + modifier == I915_FORMAT_MOD_Yf_TILED && wp->cpp == 1) |
---|
4579 | 5167 | wp->dbuf_block_size = 256; |
---|
4580 | 5168 | else |
---|
4581 | 5169 | wp->dbuf_block_size = 512; |
---|
4582 | 5170 | |
---|
4583 | | - if (drm_rotation_90_or_270(pstate->rotation)) { |
---|
4584 | | - |
---|
| 5171 | + if (drm_rotation_90_or_270(rotation)) { |
---|
4585 | 5172 | switch (wp->cpp) { |
---|
4586 | 5173 | case 1: |
---|
4587 | 5174 | wp->y_min_scanlines = 16; |
---|
.. | .. |
---|
4600 | 5187 | wp->y_min_scanlines = 4; |
---|
4601 | 5188 | } |
---|
4602 | 5189 | |
---|
4603 | | - if (apply_memory_bw_wa) |
---|
| 5190 | + if (skl_needs_memory_bw_wa(dev_priv)) |
---|
4604 | 5191 | wp->y_min_scanlines *= 2; |
---|
4605 | 5192 | |
---|
4606 | 5193 | wp->plane_bytes_per_line = wp->width * wp->cpp; |
---|
.. | .. |
---|
4609 | 5196 | wp->y_min_scanlines, |
---|
4610 | 5197 | wp->dbuf_block_size); |
---|
4611 | 5198 | |
---|
4612 | | - if (INTEL_GEN(dev_priv) >= 10) |
---|
| 5199 | + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) |
---|
4613 | 5200 | interm_pbpl++; |
---|
4614 | 5201 | |
---|
4615 | 5202 | wp->plane_blocks_per_line = div_fixed16(interm_pbpl, |
---|
4616 | 5203 | wp->y_min_scanlines); |
---|
4617 | | - } else if (wp->x_tiled && IS_GEN9(dev_priv)) { |
---|
4618 | | - interm_pbpl = DIV_ROUND_UP(wp->plane_bytes_per_line, |
---|
4619 | | - wp->dbuf_block_size); |
---|
4620 | | - wp->plane_blocks_per_line = u32_to_fixed16(interm_pbpl); |
---|
4621 | 5204 | } else { |
---|
4622 | 5205 | interm_pbpl = DIV_ROUND_UP(wp->plane_bytes_per_line, |
---|
4623 | | - wp->dbuf_block_size) + 1; |
---|
| 5206 | + wp->dbuf_block_size); |
---|
| 5207 | + |
---|
| 5208 | + if (!wp->x_tiled || |
---|
| 5209 | + INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) |
---|
| 5210 | + interm_pbpl++; |
---|
| 5211 | + |
---|
4624 | 5212 | wp->plane_blocks_per_line = u32_to_fixed16(interm_pbpl); |
---|
4625 | 5213 | } |
---|
4626 | 5214 | |
---|
4627 | 5215 | wp->y_tile_minimum = mul_u32_fixed16(wp->y_min_scanlines, |
---|
4628 | 5216 | wp->plane_blocks_per_line); |
---|
| 5217 | + |
---|
4629 | 5218 | wp->linetime_us = fixed16_to_u32_round_up( |
---|
4630 | | - intel_get_linetime_us(cstate)); |
---|
| 5219 | + intel_get_linetime_us(crtc_state)); |
---|
4631 | 5220 | |
---|
4632 | 5221 | return 0; |
---|
4633 | 5222 | } |
---|
4634 | 5223 | |
---|
4635 | | -static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, |
---|
4636 | | - struct intel_crtc_state *cstate, |
---|
4637 | | - const struct intel_plane_state *intel_pstate, |
---|
4638 | | - uint16_t ddb_allocation, |
---|
4639 | | - int level, |
---|
4640 | | - const struct skl_wm_params *wp, |
---|
4641 | | - const struct skl_wm_level *result_prev, |
---|
4642 | | - struct skl_wm_level *result /* out */) |
---|
| 5224 | +static int |
---|
| 5225 | +skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state, |
---|
| 5226 | + const struct intel_plane_state *plane_state, |
---|
| 5227 | + struct skl_wm_params *wp, int color_plane) |
---|
4643 | 5228 | { |
---|
4644 | | - const struct drm_plane_state *pstate = &intel_pstate->base; |
---|
4645 | | - uint32_t latency = dev_priv->wm.skl_latency[level]; |
---|
| 5229 | + const struct drm_framebuffer *fb = plane_state->hw.fb; |
---|
| 5230 | + int width; |
---|
| 5231 | + |
---|
| 5232 | + /* |
---|
| 5233 | + * Src coordinates are already rotated by 270 degrees for |
---|
| 5234 | + * the 90/270 degree plane rotation cases (to match the |
---|
| 5235 | + * GTT mapping), hence no need to account for rotation here. |
---|
| 5236 | + */ |
---|
| 5237 | + width = drm_rect_width(&plane_state->uapi.src) >> 16; |
---|
| 5238 | + |
---|
| 5239 | + return skl_compute_wm_params(crtc_state, width, |
---|
| 5240 | + fb->format, fb->modifier, |
---|
| 5241 | + plane_state->hw.rotation, |
---|
| 5242 | + skl_adjusted_plane_pixel_rate(crtc_state, plane_state), |
---|
| 5243 | + wp, color_plane); |
---|
| 5244 | +} |
---|
| 5245 | + |
---|
| 5246 | +static bool skl_wm_has_lines(struct drm_i915_private *dev_priv, int level) |
---|
| 5247 | +{ |
---|
| 5248 | + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) |
---|
| 5249 | + return true; |
---|
| 5250 | + |
---|
| 5251 | + /* The number of lines are ignored for the level 0 watermark. */ |
---|
| 5252 | + return level > 0; |
---|
| 5253 | +} |
---|
| 5254 | + |
---|
| 5255 | +static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, |
---|
| 5256 | + int level, |
---|
| 5257 | + unsigned int latency, |
---|
| 5258 | + const struct skl_wm_params *wp, |
---|
| 5259 | + const struct skl_wm_level *result_prev, |
---|
| 5260 | + struct skl_wm_level *result /* out */) |
---|
| 5261 | +{ |
---|
| 5262 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
4646 | 5263 | uint_fixed_16_16_t method1, method2; |
---|
4647 | 5264 | uint_fixed_16_16_t selected_result; |
---|
4648 | | - uint32_t res_blocks, res_lines; |
---|
4649 | | - struct intel_atomic_state *state = |
---|
4650 | | - to_intel_atomic_state(cstate->base.state); |
---|
4651 | | - bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state); |
---|
4652 | | - uint32_t min_disp_buf_needed; |
---|
| 5265 | + u32 res_blocks, res_lines, min_ddb_alloc = 0; |
---|
4653 | 5266 | |
---|
4654 | | - if (latency == 0 || |
---|
4655 | | - !intel_wm_plane_visible(cstate, intel_pstate)) { |
---|
4656 | | - result->plane_en = false; |
---|
4657 | | - return 0; |
---|
| 5267 | + if (latency == 0) { |
---|
| 5268 | + /* reject it */ |
---|
| 5269 | + result->min_ddb_alloc = U16_MAX; |
---|
| 5270 | + return; |
---|
4658 | 5271 | } |
---|
4659 | 5272 | |
---|
4660 | | - /* Display WA #1141: kbl,cfl */ |
---|
4661 | | - if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) || |
---|
4662 | | - IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0)) && |
---|
| 5273 | + /* |
---|
| 5274 | + * WaIncreaseLatencyIPCEnabled: kbl,cfl |
---|
| 5275 | + * Display WA #1141: kbl,cfl |
---|
| 5276 | + */ |
---|
| 5277 | + if ((IS_KABYLAKE(dev_priv) || |
---|
| 5278 | + IS_COFFEELAKE(dev_priv) || |
---|
| 5279 | + IS_COMETLAKE(dev_priv)) && |
---|
4663 | 5280 | dev_priv->ipc_enabled) |
---|
4664 | 5281 | latency += 4; |
---|
4665 | 5282 | |
---|
4666 | | - if (apply_memory_bw_wa && wp->x_tiled) |
---|
| 5283 | + if (skl_needs_memory_bw_wa(dev_priv) && wp->x_tiled) |
---|
4667 | 5284 | latency += 15; |
---|
4668 | 5285 | |
---|
4669 | 5286 | method1 = skl_wm_method1(dev_priv, wp->plane_pixel_rate, |
---|
4670 | 5287 | wp->cpp, latency, wp->dbuf_block_size); |
---|
4671 | 5288 | method2 = skl_wm_method2(wp->plane_pixel_rate, |
---|
4672 | | - cstate->base.adjusted_mode.crtc_htotal, |
---|
| 5289 | + crtc_state->hw.adjusted_mode.crtc_htotal, |
---|
4673 | 5290 | latency, |
---|
4674 | 5291 | wp->plane_blocks_per_line); |
---|
4675 | 5292 | |
---|
4676 | 5293 | if (wp->y_tiled) { |
---|
4677 | 5294 | selected_result = max_fixed16(method2, wp->y_tile_minimum); |
---|
4678 | 5295 | } else { |
---|
4679 | | - if ((wp->cpp * cstate->base.adjusted_mode.crtc_htotal / |
---|
| 5296 | + if ((wp->cpp * crtc_state->hw.adjusted_mode.crtc_htotal / |
---|
4680 | 5297 | wp->dbuf_block_size < 1) && |
---|
4681 | | - (wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) |
---|
| 5298 | + (wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) { |
---|
4682 | 5299 | selected_result = method2; |
---|
4683 | | - else if (ddb_allocation >= |
---|
4684 | | - fixed16_to_u32_round_up(wp->plane_blocks_per_line)) |
---|
4685 | | - selected_result = min_fixed16(method1, method2); |
---|
4686 | | - else if (latency >= wp->linetime_us) |
---|
4687 | | - selected_result = min_fixed16(method1, method2); |
---|
4688 | | - else |
---|
| 5300 | + } else if (latency >= wp->linetime_us) { |
---|
| 5301 | + if (IS_GEN(dev_priv, 9) && |
---|
| 5302 | + !IS_GEMINILAKE(dev_priv)) |
---|
| 5303 | + selected_result = min_fixed16(method1, method2); |
---|
| 5304 | + else |
---|
| 5305 | + selected_result = method2; |
---|
| 5306 | + } else { |
---|
4689 | 5307 | selected_result = method1; |
---|
| 5308 | + } |
---|
4690 | 5309 | } |
---|
4691 | 5310 | |
---|
4692 | 5311 | res_blocks = fixed16_to_u32_round_up(selected_result) + 1; |
---|
4693 | 5312 | res_lines = div_round_up_fixed16(selected_result, |
---|
4694 | 5313 | wp->plane_blocks_per_line); |
---|
4695 | 5314 | |
---|
4696 | | - /* Display WA #1125: skl,bxt,kbl,glk */ |
---|
4697 | | - if (level == 0 && wp->rc_surface) |
---|
4698 | | - res_blocks += fixed16_to_u32_round_up(wp->y_tile_minimum); |
---|
| 5315 | + if (IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv)) { |
---|
| 5316 | + /* Display WA #1125: skl,bxt,kbl */ |
---|
| 5317 | + if (level == 0 && wp->rc_surface) |
---|
| 5318 | + res_blocks += |
---|
| 5319 | + fixed16_to_u32_round_up(wp->y_tile_minimum); |
---|
4699 | 5320 | |
---|
4700 | | - /* Display WA #1126: skl,bxt,kbl,glk */ |
---|
4701 | | - if (level >= 1 && level <= 7) { |
---|
4702 | | - if (wp->y_tiled) { |
---|
4703 | | - res_blocks += fixed16_to_u32_round_up( |
---|
4704 | | - wp->y_tile_minimum); |
---|
4705 | | - res_lines += wp->y_min_scanlines; |
---|
4706 | | - } else { |
---|
4707 | | - res_blocks++; |
---|
| 5321 | + /* Display WA #1126: skl,bxt,kbl */ |
---|
| 5322 | + if (level >= 1 && level <= 7) { |
---|
| 5323 | + if (wp->y_tiled) { |
---|
| 5324 | + res_blocks += |
---|
| 5325 | + fixed16_to_u32_round_up(wp->y_tile_minimum); |
---|
| 5326 | + res_lines += wp->y_min_scanlines; |
---|
| 5327 | + } else { |
---|
| 5328 | + res_blocks++; |
---|
| 5329 | + } |
---|
| 5330 | + |
---|
| 5331 | + /* |
---|
| 5332 | + * Make sure result blocks for higher latency levels are |
---|
| 5333 | + * atleast as high as level below the current level. |
---|
| 5334 | + * Assumption in DDB algorithm optimization for special |
---|
| 5335 | + * cases. Also covers Display WA #1125 for RC. |
---|
| 5336 | + */ |
---|
| 5337 | + if (result_prev->plane_res_b > res_blocks) |
---|
| 5338 | + res_blocks = result_prev->plane_res_b; |
---|
4708 | 5339 | } |
---|
4709 | | - |
---|
4710 | | - /* |
---|
4711 | | - * Make sure result blocks for higher latency levels are atleast |
---|
4712 | | - * as high as level below the current level. |
---|
4713 | | - * Assumption in DDB algorithm optimization for special cases. |
---|
4714 | | - * Also covers Display WA #1125 for RC. |
---|
4715 | | - */ |
---|
4716 | | - if (result_prev->plane_res_b > res_blocks) |
---|
4717 | | - res_blocks = result_prev->plane_res_b; |
---|
4718 | 5340 | } |
---|
4719 | 5341 | |
---|
4720 | 5342 | if (INTEL_GEN(dev_priv) >= 11) { |
---|
4721 | 5343 | if (wp->y_tiled) { |
---|
4722 | | - uint32_t extra_lines; |
---|
4723 | | - uint_fixed_16_16_t fp_min_disp_buf_needed; |
---|
| 5344 | + int extra_lines; |
---|
4724 | 5345 | |
---|
4725 | 5346 | if (res_lines % wp->y_min_scanlines == 0) |
---|
4726 | 5347 | extra_lines = wp->y_min_scanlines; |
---|
4727 | 5348 | else |
---|
4728 | 5349 | extra_lines = wp->y_min_scanlines * 2 - |
---|
4729 | | - res_lines % wp->y_min_scanlines; |
---|
| 5350 | + res_lines % wp->y_min_scanlines; |
---|
4730 | 5351 | |
---|
4731 | | - fp_min_disp_buf_needed = mul_u32_fixed16(res_lines + |
---|
4732 | | - extra_lines, |
---|
4733 | | - wp->plane_blocks_per_line); |
---|
4734 | | - min_disp_buf_needed = fixed16_to_u32_round_up( |
---|
4735 | | - fp_min_disp_buf_needed); |
---|
| 5352 | + min_ddb_alloc = mul_round_up_u32_fixed16(res_lines + extra_lines, |
---|
| 5353 | + wp->plane_blocks_per_line); |
---|
4736 | 5354 | } else { |
---|
4737 | | - min_disp_buf_needed = DIV_ROUND_UP(res_blocks * 11, 10); |
---|
| 5355 | + min_ddb_alloc = res_blocks + |
---|
| 5356 | + DIV_ROUND_UP(res_blocks, 10); |
---|
4738 | 5357 | } |
---|
4739 | | - } else { |
---|
4740 | | - min_disp_buf_needed = res_blocks; |
---|
4741 | 5358 | } |
---|
4742 | 5359 | |
---|
4743 | | - if ((level > 0 && res_lines > 31) || |
---|
4744 | | - res_blocks >= ddb_allocation || |
---|
4745 | | - min_disp_buf_needed >= ddb_allocation) { |
---|
4746 | | - result->plane_en = false; |
---|
| 5360 | + if (!skl_wm_has_lines(dev_priv, level)) |
---|
| 5361 | + res_lines = 0; |
---|
4747 | 5362 | |
---|
4748 | | - /* |
---|
4749 | | - * If there are no valid level 0 watermarks, then we can't |
---|
4750 | | - * support this display configuration. |
---|
4751 | | - */ |
---|
4752 | | - if (level) { |
---|
4753 | | - return 0; |
---|
4754 | | - } else { |
---|
4755 | | - struct drm_plane *plane = pstate->plane; |
---|
4756 | | - |
---|
4757 | | - DRM_DEBUG_KMS("Requested display configuration exceeds system watermark limitations\n"); |
---|
4758 | | - DRM_DEBUG_KMS("[PLANE:%d:%s] blocks required = %u/%u, lines required = %u/31\n", |
---|
4759 | | - plane->base.id, plane->name, |
---|
4760 | | - res_blocks, ddb_allocation, res_lines); |
---|
4761 | | - return -EINVAL; |
---|
4762 | | - } |
---|
| 5363 | + if (res_lines > 31) { |
---|
| 5364 | + /* reject it */ |
---|
| 5365 | + result->min_ddb_alloc = U16_MAX; |
---|
| 5366 | + return; |
---|
4763 | 5367 | } |
---|
4764 | 5368 | |
---|
4765 | 5369 | /* |
---|
4766 | | - * Display WA #826 (SKL:ALL, BXT:ALL) & #1059 (CNL:A) |
---|
4767 | | - * disable wm level 1-7 on NV12 planes |
---|
| 5370 | + * If res_lines is valid, assume we can use this watermark level |
---|
| 5371 | + * for now. We'll come back and disable it after we calculate the |
---|
| 5372 | + * DDB allocation if it turns out we don't actually have enough |
---|
| 5373 | + * blocks to satisfy it. |
---|
4768 | 5374 | */ |
---|
4769 | | - if (wp->is_planar && level >= 1 && |
---|
4770 | | - (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv) || |
---|
4771 | | - IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0))) { |
---|
4772 | | - result->plane_en = false; |
---|
4773 | | - return 0; |
---|
4774 | | - } |
---|
4775 | | - |
---|
4776 | | - /* The number of lines are ignored for the level 0 watermark. */ |
---|
4777 | 5375 | result->plane_res_b = res_blocks; |
---|
4778 | 5376 | result->plane_res_l = res_lines; |
---|
| 5377 | + /* Bspec says: value >= plane ddb allocation -> invalid, hence the +1 here */ |
---|
| 5378 | + result->min_ddb_alloc = max(min_ddb_alloc, res_blocks) + 1; |
---|
4779 | 5379 | result->plane_en = true; |
---|
| 5380 | +} |
---|
| 5381 | + |
---|
| 5382 | +static void |
---|
| 5383 | +skl_compute_wm_levels(const struct intel_crtc_state *crtc_state, |
---|
| 5384 | + const struct skl_wm_params *wm_params, |
---|
| 5385 | + struct skl_wm_level *levels) |
---|
| 5386 | +{ |
---|
| 5387 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
| 5388 | + int level, max_level = ilk_wm_max_level(dev_priv); |
---|
| 5389 | + struct skl_wm_level *result_prev = &levels[0]; |
---|
| 5390 | + |
---|
| 5391 | + for (level = 0; level <= max_level; level++) { |
---|
| 5392 | + struct skl_wm_level *result = &levels[level]; |
---|
| 5393 | + unsigned int latency = dev_priv->wm.skl_latency[level]; |
---|
| 5394 | + |
---|
| 5395 | + skl_compute_plane_wm(crtc_state, level, latency, |
---|
| 5396 | + wm_params, result_prev, result); |
---|
| 5397 | + |
---|
| 5398 | + result_prev = result; |
---|
| 5399 | + } |
---|
| 5400 | +} |
---|
| 5401 | + |
---|
| 5402 | +static void tgl_compute_sagv_wm(const struct intel_crtc_state *crtc_state, |
---|
| 5403 | + const struct skl_wm_params *wm_params, |
---|
| 5404 | + struct skl_plane_wm *plane_wm) |
---|
| 5405 | +{ |
---|
| 5406 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
| 5407 | + struct skl_wm_level *sagv_wm = &plane_wm->sagv_wm0; |
---|
| 5408 | + struct skl_wm_level *levels = plane_wm->wm; |
---|
| 5409 | + unsigned int latency = dev_priv->wm.skl_latency[0] + dev_priv->sagv_block_time_us; |
---|
| 5410 | + |
---|
| 5411 | + skl_compute_plane_wm(crtc_state, 0, latency, |
---|
| 5412 | + wm_params, &levels[0], |
---|
| 5413 | + sagv_wm); |
---|
| 5414 | +} |
---|
| 5415 | + |
---|
| 5416 | +static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state, |
---|
| 5417 | + const struct skl_wm_params *wp, |
---|
| 5418 | + struct skl_plane_wm *wm) |
---|
| 5419 | +{ |
---|
| 5420 | + struct drm_device *dev = crtc_state->uapi.crtc->dev; |
---|
| 5421 | + const struct drm_i915_private *dev_priv = to_i915(dev); |
---|
| 5422 | + u16 trans_min, trans_amount, trans_y_tile_min; |
---|
| 5423 | + u16 wm0_sel_res_b, trans_offset_b, res_blocks; |
---|
| 5424 | + |
---|
| 5425 | + /* Transition WM don't make any sense if ipc is disabled */ |
---|
| 5426 | + if (!dev_priv->ipc_enabled) |
---|
| 5427 | + return; |
---|
| 5428 | + |
---|
| 5429 | + /* |
---|
| 5430 | + * WaDisableTWM:skl,kbl,cfl,bxt |
---|
| 5431 | + * Transition WM are not recommended by HW team for GEN9 |
---|
| 5432 | + */ |
---|
| 5433 | + if (IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv)) |
---|
| 5434 | + return; |
---|
| 5435 | + |
---|
| 5436 | + if (INTEL_GEN(dev_priv) >= 11) |
---|
| 5437 | + trans_min = 4; |
---|
| 5438 | + else |
---|
| 5439 | + trans_min = 14; |
---|
| 5440 | + |
---|
| 5441 | + /* Display WA #1140: glk,cnl */ |
---|
| 5442 | + if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) |
---|
| 5443 | + trans_amount = 0; |
---|
| 5444 | + else |
---|
| 5445 | + trans_amount = 10; /* This is configurable amount */ |
---|
| 5446 | + |
---|
| 5447 | + trans_offset_b = trans_min + trans_amount; |
---|
| 5448 | + |
---|
| 5449 | + /* |
---|
| 5450 | + * The spec asks for Selected Result Blocks for wm0 (the real value), |
---|
| 5451 | + * not Result Blocks (the integer value). Pay attention to the capital |
---|
| 5452 | + * letters. The value wm_l0->plane_res_b is actually Result Blocks, but |
---|
| 5453 | + * since Result Blocks is the ceiling of Selected Result Blocks plus 1, |
---|
| 5454 | + * and since we later will have to get the ceiling of the sum in the |
---|
| 5455 | + * transition watermarks calculation, we can just pretend Selected |
---|
| 5456 | + * Result Blocks is Result Blocks minus 1 and it should work for the |
---|
| 5457 | + * current platforms. |
---|
| 5458 | + */ |
---|
| 5459 | + wm0_sel_res_b = wm->wm[0].plane_res_b - 1; |
---|
| 5460 | + |
---|
| 5461 | + if (wp->y_tiled) { |
---|
| 5462 | + trans_y_tile_min = |
---|
| 5463 | + (u16)mul_round_up_u32_fixed16(2, wp->y_tile_minimum); |
---|
| 5464 | + res_blocks = max(wm0_sel_res_b, trans_y_tile_min) + |
---|
| 5465 | + trans_offset_b; |
---|
| 5466 | + } else { |
---|
| 5467 | + res_blocks = wm0_sel_res_b + trans_offset_b; |
---|
| 5468 | + } |
---|
| 5469 | + |
---|
| 5470 | + /* |
---|
| 5471 | + * Just assume we can enable the transition watermark. After |
---|
| 5472 | + * computing the DDB we'll come back and disable it if that |
---|
| 5473 | + * assumption turns out to be false. |
---|
| 5474 | + */ |
---|
| 5475 | + wm->trans_wm.plane_res_b = res_blocks + 1; |
---|
| 5476 | + wm->trans_wm.plane_en = true; |
---|
| 5477 | +} |
---|
| 5478 | + |
---|
| 5479 | +static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state, |
---|
| 5480 | + const struct intel_plane_state *plane_state, |
---|
| 5481 | + enum plane_id plane_id, int color_plane) |
---|
| 5482 | +{ |
---|
| 5483 | + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
---|
| 5484 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 5485 | + struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id]; |
---|
| 5486 | + struct skl_wm_params wm_params; |
---|
| 5487 | + int ret; |
---|
| 5488 | + |
---|
| 5489 | + ret = skl_compute_plane_wm_params(crtc_state, plane_state, |
---|
| 5490 | + &wm_params, color_plane); |
---|
| 5491 | + if (ret) |
---|
| 5492 | + return ret; |
---|
| 5493 | + |
---|
| 5494 | + skl_compute_wm_levels(crtc_state, &wm_params, wm->wm); |
---|
| 5495 | + |
---|
| 5496 | + if (INTEL_GEN(dev_priv) >= 12) |
---|
| 5497 | + tgl_compute_sagv_wm(crtc_state, &wm_params, wm); |
---|
| 5498 | + |
---|
| 5499 | + skl_compute_transition_wm(crtc_state, &wm_params, wm); |
---|
4780 | 5500 | |
---|
4781 | 5501 | return 0; |
---|
4782 | 5502 | } |
---|
4783 | 5503 | |
---|
4784 | | -static int |
---|
4785 | | -skl_compute_wm_levels(const struct drm_i915_private *dev_priv, |
---|
4786 | | - struct skl_ddb_allocation *ddb, |
---|
4787 | | - struct intel_crtc_state *cstate, |
---|
4788 | | - const struct intel_plane_state *intel_pstate, |
---|
4789 | | - const struct skl_wm_params *wm_params, |
---|
4790 | | - struct skl_plane_wm *wm, |
---|
4791 | | - int plane_id) |
---|
| 5504 | +static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state, |
---|
| 5505 | + const struct intel_plane_state *plane_state, |
---|
| 5506 | + enum plane_id plane_id) |
---|
4792 | 5507 | { |
---|
4793 | | - struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); |
---|
4794 | | - struct drm_plane *plane = intel_pstate->base.plane; |
---|
4795 | | - struct intel_plane *intel_plane = to_intel_plane(plane); |
---|
4796 | | - uint16_t ddb_blocks; |
---|
4797 | | - enum pipe pipe = intel_crtc->pipe; |
---|
4798 | | - int level, max_level = ilk_wm_max_level(dev_priv); |
---|
4799 | | - enum plane_id intel_plane_id = intel_plane->id; |
---|
| 5508 | + struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id]; |
---|
| 5509 | + struct skl_wm_params wm_params; |
---|
4800 | 5510 | int ret; |
---|
4801 | 5511 | |
---|
4802 | | - if (WARN_ON(!intel_pstate->base.fb)) |
---|
4803 | | - return -EINVAL; |
---|
| 5512 | + wm->is_planar = true; |
---|
4804 | 5513 | |
---|
4805 | | - ddb_blocks = plane_id ? |
---|
4806 | | - skl_ddb_entry_size(&ddb->uv_plane[pipe][intel_plane_id]) : |
---|
4807 | | - skl_ddb_entry_size(&ddb->plane[pipe][intel_plane_id]); |
---|
| 5514 | + /* uv plane watermarks must also be validated for NV12/Planar */ |
---|
| 5515 | + ret = skl_compute_plane_wm_params(crtc_state, plane_state, |
---|
| 5516 | + &wm_params, 1); |
---|
| 5517 | + if (ret) |
---|
| 5518 | + return ret; |
---|
4808 | 5519 | |
---|
4809 | | - for (level = 0; level <= max_level; level++) { |
---|
4810 | | - struct skl_wm_level *result = plane_id ? &wm->uv_wm[level] : |
---|
4811 | | - &wm->wm[level]; |
---|
4812 | | - struct skl_wm_level *result_prev; |
---|
| 5520 | + skl_compute_wm_levels(crtc_state, &wm_params, wm->uv_wm); |
---|
4813 | 5521 | |
---|
4814 | | - if (level) |
---|
4815 | | - result_prev = plane_id ? &wm->uv_wm[level - 1] : |
---|
4816 | | - &wm->wm[level - 1]; |
---|
4817 | | - else |
---|
4818 | | - result_prev = plane_id ? &wm->uv_wm[0] : &wm->wm[0]; |
---|
| 5522 | + return 0; |
---|
| 5523 | +} |
---|
4819 | 5524 | |
---|
4820 | | - ret = skl_compute_plane_wm(dev_priv, |
---|
4821 | | - cstate, |
---|
4822 | | - intel_pstate, |
---|
4823 | | - ddb_blocks, |
---|
4824 | | - level, |
---|
4825 | | - wm_params, |
---|
4826 | | - result_prev, |
---|
4827 | | - result); |
---|
| 5525 | +static int skl_build_plane_wm(struct intel_crtc_state *crtc_state, |
---|
| 5526 | + const struct intel_plane_state *plane_state) |
---|
| 5527 | +{ |
---|
| 5528 | + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); |
---|
| 5529 | + const struct drm_framebuffer *fb = plane_state->hw.fb; |
---|
| 5530 | + enum plane_id plane_id = plane->id; |
---|
| 5531 | + int ret; |
---|
| 5532 | + |
---|
| 5533 | + if (!intel_wm_plane_visible(crtc_state, plane_state)) |
---|
| 5534 | + return 0; |
---|
| 5535 | + |
---|
| 5536 | + ret = skl_build_plane_wm_single(crtc_state, plane_state, |
---|
| 5537 | + plane_id, 0); |
---|
| 5538 | + if (ret) |
---|
| 5539 | + return ret; |
---|
| 5540 | + |
---|
| 5541 | + if (fb->format->is_yuv && fb->format->num_planes > 1) { |
---|
| 5542 | + ret = skl_build_plane_wm_uv(crtc_state, plane_state, |
---|
| 5543 | + plane_id); |
---|
4828 | 5544 | if (ret) |
---|
4829 | 5545 | return ret; |
---|
4830 | 5546 | } |
---|
4831 | 5547 | |
---|
4832 | | - if (intel_pstate->base.fb->format->format == DRM_FORMAT_NV12) |
---|
4833 | | - wm->is_planar = true; |
---|
| 5548 | + return 0; |
---|
| 5549 | +} |
---|
| 5550 | + |
---|
| 5551 | +static int icl_build_plane_wm(struct intel_crtc_state *crtc_state, |
---|
| 5552 | + const struct intel_plane_state *plane_state) |
---|
| 5553 | +{ |
---|
| 5554 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
| 5555 | + enum plane_id plane_id = to_intel_plane(plane_state->uapi.plane)->id; |
---|
| 5556 | + int ret; |
---|
| 5557 | + |
---|
| 5558 | + /* Watermarks calculated in master */ |
---|
| 5559 | + if (plane_state->planar_slave) |
---|
| 5560 | + return 0; |
---|
| 5561 | + |
---|
| 5562 | + if (plane_state->planar_linked_plane) { |
---|
| 5563 | + const struct drm_framebuffer *fb = plane_state->hw.fb; |
---|
| 5564 | + enum plane_id y_plane_id = plane_state->planar_linked_plane->id; |
---|
| 5565 | + |
---|
| 5566 | + drm_WARN_ON(&dev_priv->drm, |
---|
| 5567 | + !intel_wm_plane_visible(crtc_state, plane_state)); |
---|
| 5568 | + drm_WARN_ON(&dev_priv->drm, !fb->format->is_yuv || |
---|
| 5569 | + fb->format->num_planes == 1); |
---|
| 5570 | + |
---|
| 5571 | + ret = skl_build_plane_wm_single(crtc_state, plane_state, |
---|
| 5572 | + y_plane_id, 0); |
---|
| 5573 | + if (ret) |
---|
| 5574 | + return ret; |
---|
| 5575 | + |
---|
| 5576 | + ret = skl_build_plane_wm_single(crtc_state, plane_state, |
---|
| 5577 | + plane_id, 1); |
---|
| 5578 | + if (ret) |
---|
| 5579 | + return ret; |
---|
| 5580 | + } else if (intel_wm_plane_visible(crtc_state, plane_state)) { |
---|
| 5581 | + ret = skl_build_plane_wm_single(crtc_state, plane_state, |
---|
| 5582 | + plane_id, 0); |
---|
| 5583 | + if (ret) |
---|
| 5584 | + return ret; |
---|
| 5585 | + } |
---|
4834 | 5586 | |
---|
4835 | 5587 | return 0; |
---|
4836 | 5588 | } |
---|
4837 | 5589 | |
---|
4838 | | -static uint32_t |
---|
4839 | | -skl_compute_linetime_wm(struct intel_crtc_state *cstate) |
---|
| 5590 | +static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state) |
---|
4840 | 5591 | { |
---|
4841 | | - struct drm_atomic_state *state = cstate->base.state; |
---|
4842 | | - struct drm_i915_private *dev_priv = to_i915(state->dev); |
---|
4843 | | - uint_fixed_16_16_t linetime_us; |
---|
4844 | | - uint32_t linetime_wm; |
---|
4845 | | - |
---|
4846 | | - linetime_us = intel_get_linetime_us(cstate); |
---|
4847 | | - |
---|
4848 | | - if (is_fixed16_zero(linetime_us)) |
---|
4849 | | - return 0; |
---|
4850 | | - |
---|
4851 | | - linetime_wm = fixed16_to_u32_round_up(mul_u32_fixed16(8, linetime_us)); |
---|
4852 | | - |
---|
4853 | | - /* Display WA #1135: bxt:ALL GLK:ALL */ |
---|
4854 | | - if ((IS_BROXTON(dev_priv) || IS_GEMINILAKE(dev_priv)) && |
---|
4855 | | - dev_priv->ipc_enabled) |
---|
4856 | | - linetime_wm /= 2; |
---|
4857 | | - |
---|
4858 | | - return linetime_wm; |
---|
4859 | | -} |
---|
4860 | | - |
---|
4861 | | -static void skl_compute_transition_wm(struct intel_crtc_state *cstate, |
---|
4862 | | - struct skl_wm_params *wp, |
---|
4863 | | - struct skl_wm_level *wm_l0, |
---|
4864 | | - uint16_t ddb_allocation, |
---|
4865 | | - struct skl_wm_level *trans_wm /* out */) |
---|
4866 | | -{ |
---|
4867 | | - struct drm_device *dev = cstate->base.crtc->dev; |
---|
4868 | | - const struct drm_i915_private *dev_priv = to_i915(dev); |
---|
4869 | | - uint16_t trans_min, trans_y_tile_min; |
---|
4870 | | - const uint16_t trans_amount = 10; /* This is configurable amount */ |
---|
4871 | | - uint16_t trans_offset_b, res_blocks; |
---|
4872 | | - |
---|
4873 | | - if (!cstate->base.active) |
---|
4874 | | - goto exit; |
---|
4875 | | - |
---|
4876 | | - /* Transition WM are not recommended by HW team for GEN9 */ |
---|
4877 | | - if (INTEL_GEN(dev_priv) <= 9) |
---|
4878 | | - goto exit; |
---|
4879 | | - |
---|
4880 | | - /* Transition WM don't make any sense if ipc is disabled */ |
---|
4881 | | - if (!dev_priv->ipc_enabled) |
---|
4882 | | - goto exit; |
---|
4883 | | - |
---|
4884 | | - trans_min = 0; |
---|
4885 | | - if (INTEL_GEN(dev_priv) >= 10) |
---|
4886 | | - trans_min = 4; |
---|
4887 | | - |
---|
4888 | | - trans_offset_b = trans_min + trans_amount; |
---|
4889 | | - |
---|
4890 | | - if (wp->y_tiled) { |
---|
4891 | | - trans_y_tile_min = (uint16_t) mul_round_up_u32_fixed16(2, |
---|
4892 | | - wp->y_tile_minimum); |
---|
4893 | | - res_blocks = max(wm_l0->plane_res_b, trans_y_tile_min) + |
---|
4894 | | - trans_offset_b; |
---|
4895 | | - } else { |
---|
4896 | | - res_blocks = wm_l0->plane_res_b + trans_offset_b; |
---|
4897 | | - |
---|
4898 | | - /* WA BUG:1938466 add one block for non y-tile planes */ |
---|
4899 | | - if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_A0)) |
---|
4900 | | - res_blocks += 1; |
---|
4901 | | - |
---|
4902 | | - } |
---|
4903 | | - |
---|
4904 | | - res_blocks += 1; |
---|
4905 | | - |
---|
4906 | | - if (res_blocks < ddb_allocation) { |
---|
4907 | | - trans_wm->plane_res_b = res_blocks; |
---|
4908 | | - trans_wm->plane_en = true; |
---|
4909 | | - return; |
---|
4910 | | - } |
---|
4911 | | - |
---|
4912 | | -exit: |
---|
4913 | | - trans_wm->plane_en = false; |
---|
4914 | | -} |
---|
4915 | | - |
---|
4916 | | -static int skl_build_pipe_wm(struct intel_crtc_state *cstate, |
---|
4917 | | - struct skl_ddb_allocation *ddb, |
---|
4918 | | - struct skl_pipe_wm *pipe_wm) |
---|
4919 | | -{ |
---|
4920 | | - struct drm_device *dev = cstate->base.crtc->dev; |
---|
4921 | | - struct drm_crtc_state *crtc_state = &cstate->base; |
---|
4922 | | - const struct drm_i915_private *dev_priv = to_i915(dev); |
---|
4923 | | - struct drm_plane *plane; |
---|
4924 | | - const struct drm_plane_state *pstate; |
---|
4925 | | - struct skl_plane_wm *wm; |
---|
| 5592 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); |
---|
| 5593 | + struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal; |
---|
| 5594 | + struct intel_plane *plane; |
---|
| 5595 | + const struct intel_plane_state *plane_state; |
---|
4926 | 5596 | int ret; |
---|
4927 | 5597 | |
---|
4928 | 5598 | /* |
---|
.. | .. |
---|
4931 | 5601 | */ |
---|
4932 | 5602 | memset(pipe_wm->planes, 0, sizeof(pipe_wm->planes)); |
---|
4933 | 5603 | |
---|
4934 | | - drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { |
---|
4935 | | - const struct intel_plane_state *intel_pstate = |
---|
4936 | | - to_intel_plane_state(pstate); |
---|
4937 | | - enum plane_id plane_id = to_intel_plane(plane)->id; |
---|
4938 | | - struct skl_wm_params wm_params; |
---|
4939 | | - enum pipe pipe = to_intel_crtc(cstate->base.crtc)->pipe; |
---|
4940 | | - uint16_t ddb_blocks; |
---|
| 5604 | + intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, |
---|
| 5605 | + crtc_state) { |
---|
4941 | 5606 | |
---|
4942 | | - wm = &pipe_wm->planes[plane_id]; |
---|
4943 | | - ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][plane_id]); |
---|
4944 | | - |
---|
4945 | | - ret = skl_compute_plane_wm_params(dev_priv, cstate, |
---|
4946 | | - intel_pstate, &wm_params, 0); |
---|
| 5607 | + if (INTEL_GEN(dev_priv) >= 11) |
---|
| 5608 | + ret = icl_build_plane_wm(crtc_state, plane_state); |
---|
| 5609 | + else |
---|
| 5610 | + ret = skl_build_plane_wm(crtc_state, plane_state); |
---|
4947 | 5611 | if (ret) |
---|
4948 | 5612 | return ret; |
---|
4949 | | - |
---|
4950 | | - ret = skl_compute_wm_levels(dev_priv, ddb, cstate, |
---|
4951 | | - intel_pstate, &wm_params, wm, 0); |
---|
4952 | | - if (ret) |
---|
4953 | | - return ret; |
---|
4954 | | - |
---|
4955 | | - skl_compute_transition_wm(cstate, &wm_params, &wm->wm[0], |
---|
4956 | | - ddb_blocks, &wm->trans_wm); |
---|
4957 | | - |
---|
4958 | | - /* uv plane watermarks must also be validated for NV12/Planar */ |
---|
4959 | | - if (wm_params.is_planar) { |
---|
4960 | | - memset(&wm_params, 0, sizeof(struct skl_wm_params)); |
---|
4961 | | - wm->is_planar = true; |
---|
4962 | | - |
---|
4963 | | - ret = skl_compute_plane_wm_params(dev_priv, cstate, |
---|
4964 | | - intel_pstate, |
---|
4965 | | - &wm_params, 1); |
---|
4966 | | - if (ret) |
---|
4967 | | - return ret; |
---|
4968 | | - |
---|
4969 | | - ret = skl_compute_wm_levels(dev_priv, ddb, cstate, |
---|
4970 | | - intel_pstate, &wm_params, |
---|
4971 | | - wm, 1); |
---|
4972 | | - if (ret) |
---|
4973 | | - return ret; |
---|
4974 | | - } |
---|
4975 | 5613 | } |
---|
4976 | | - |
---|
4977 | | - pipe_wm->linetime = skl_compute_linetime_wm(cstate); |
---|
4978 | 5614 | |
---|
4979 | 5615 | return 0; |
---|
4980 | 5616 | } |
---|
.. | .. |
---|
4984 | 5620 | const struct skl_ddb_entry *entry) |
---|
4985 | 5621 | { |
---|
4986 | 5622 | if (entry->end) |
---|
4987 | | - I915_WRITE(reg, (entry->end - 1) << 16 | entry->start); |
---|
| 5623 | + intel_de_write_fw(dev_priv, reg, |
---|
| 5624 | + (entry->end - 1) << 16 | entry->start); |
---|
4988 | 5625 | else |
---|
4989 | | - I915_WRITE(reg, 0); |
---|
| 5626 | + intel_de_write_fw(dev_priv, reg, 0); |
---|
4990 | 5627 | } |
---|
4991 | 5628 | |
---|
4992 | 5629 | static void skl_write_wm_level(struct drm_i915_private *dev_priv, |
---|
4993 | 5630 | i915_reg_t reg, |
---|
4994 | 5631 | const struct skl_wm_level *level) |
---|
4995 | 5632 | { |
---|
4996 | | - uint32_t val = 0; |
---|
| 5633 | + u32 val = 0; |
---|
4997 | 5634 | |
---|
4998 | | - if (level->plane_en) { |
---|
| 5635 | + if (level->plane_en) |
---|
4999 | 5636 | val |= PLANE_WM_EN; |
---|
5000 | | - val |= level->plane_res_b; |
---|
5001 | | - val |= level->plane_res_l << PLANE_WM_LINES_SHIFT; |
---|
5002 | | - } |
---|
| 5637 | + if (level->ignore_lines) |
---|
| 5638 | + val |= PLANE_WM_IGNORE_LINES; |
---|
| 5639 | + val |= level->plane_res_b; |
---|
| 5640 | + val |= level->plane_res_l << PLANE_WM_LINES_SHIFT; |
---|
5003 | 5641 | |
---|
5004 | | - I915_WRITE(reg, val); |
---|
| 5642 | + intel_de_write_fw(dev_priv, reg, val); |
---|
5005 | 5643 | } |
---|
5006 | 5644 | |
---|
5007 | | -static void skl_write_plane_wm(struct intel_crtc *intel_crtc, |
---|
5008 | | - const struct skl_plane_wm *wm, |
---|
5009 | | - const struct skl_ddb_allocation *ddb, |
---|
5010 | | - enum plane_id plane_id) |
---|
| 5645 | +void skl_write_plane_wm(struct intel_plane *plane, |
---|
| 5646 | + const struct intel_crtc_state *crtc_state) |
---|
5011 | 5647 | { |
---|
5012 | | - struct drm_crtc *crtc = &intel_crtc->base; |
---|
5013 | | - struct drm_device *dev = crtc->dev; |
---|
5014 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
| 5648 | + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
---|
5015 | 5649 | int level, max_level = ilk_wm_max_level(dev_priv); |
---|
5016 | | - enum pipe pipe = intel_crtc->pipe; |
---|
| 5650 | + enum plane_id plane_id = plane->id; |
---|
| 5651 | + enum pipe pipe = plane->pipe; |
---|
| 5652 | + const struct skl_plane_wm *wm = |
---|
| 5653 | + &crtc_state->wm.skl.optimal.planes[plane_id]; |
---|
| 5654 | + const struct skl_ddb_entry *ddb_y = |
---|
| 5655 | + &crtc_state->wm.skl.plane_ddb_y[plane_id]; |
---|
| 5656 | + const struct skl_ddb_entry *ddb_uv = |
---|
| 5657 | + &crtc_state->wm.skl.plane_ddb_uv[plane_id]; |
---|
5017 | 5658 | |
---|
5018 | 5659 | for (level = 0; level <= max_level; level++) { |
---|
| 5660 | + const struct skl_wm_level *wm_level; |
---|
| 5661 | + |
---|
| 5662 | + wm_level = skl_plane_wm_level(crtc_state, plane_id, level); |
---|
| 5663 | + |
---|
5019 | 5664 | skl_write_wm_level(dev_priv, PLANE_WM(pipe, plane_id, level), |
---|
5020 | | - &wm->wm[level]); |
---|
| 5665 | + wm_level); |
---|
5021 | 5666 | } |
---|
5022 | 5667 | skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane_id), |
---|
5023 | 5668 | &wm->trans_wm); |
---|
5024 | 5669 | |
---|
5025 | | - skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id), |
---|
5026 | | - &ddb->plane[pipe][plane_id]); |
---|
5027 | | - if (INTEL_GEN(dev_priv) >= 11) |
---|
5028 | | - return skl_ddb_entry_write(dev_priv, |
---|
5029 | | - PLANE_BUF_CFG(pipe, plane_id), |
---|
5030 | | - &ddb->plane[pipe][plane_id]); |
---|
5031 | | - if (wm->is_planar) { |
---|
5032 | | - skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id), |
---|
5033 | | - &ddb->uv_plane[pipe][plane_id]); |
---|
| 5670 | + if (INTEL_GEN(dev_priv) >= 11) { |
---|
5034 | 5671 | skl_ddb_entry_write(dev_priv, |
---|
5035 | | - PLANE_NV12_BUF_CFG(pipe, plane_id), |
---|
5036 | | - &ddb->plane[pipe][plane_id]); |
---|
5037 | | - } else { |
---|
5038 | | - skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id), |
---|
5039 | | - &ddb->plane[pipe][plane_id]); |
---|
5040 | | - I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0); |
---|
| 5672 | + PLANE_BUF_CFG(pipe, plane_id), ddb_y); |
---|
| 5673 | + return; |
---|
5041 | 5674 | } |
---|
| 5675 | + |
---|
| 5676 | + if (wm->is_planar) |
---|
| 5677 | + swap(ddb_y, ddb_uv); |
---|
| 5678 | + |
---|
| 5679 | + skl_ddb_entry_write(dev_priv, |
---|
| 5680 | + PLANE_BUF_CFG(pipe, plane_id), ddb_y); |
---|
| 5681 | + skl_ddb_entry_write(dev_priv, |
---|
| 5682 | + PLANE_NV12_BUF_CFG(pipe, plane_id), ddb_uv); |
---|
5042 | 5683 | } |
---|
5043 | 5684 | |
---|
5044 | | -static void skl_write_cursor_wm(struct intel_crtc *intel_crtc, |
---|
5045 | | - const struct skl_plane_wm *wm, |
---|
5046 | | - const struct skl_ddb_allocation *ddb) |
---|
| 5685 | +void skl_write_cursor_wm(struct intel_plane *plane, |
---|
| 5686 | + const struct intel_crtc_state *crtc_state) |
---|
5047 | 5687 | { |
---|
5048 | | - struct drm_crtc *crtc = &intel_crtc->base; |
---|
5049 | | - struct drm_device *dev = crtc->dev; |
---|
5050 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
| 5688 | + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); |
---|
5051 | 5689 | int level, max_level = ilk_wm_max_level(dev_priv); |
---|
5052 | | - enum pipe pipe = intel_crtc->pipe; |
---|
| 5690 | + enum plane_id plane_id = plane->id; |
---|
| 5691 | + enum pipe pipe = plane->pipe; |
---|
| 5692 | + const struct skl_plane_wm *wm = |
---|
| 5693 | + &crtc_state->wm.skl.optimal.planes[plane_id]; |
---|
| 5694 | + const struct skl_ddb_entry *ddb = |
---|
| 5695 | + &crtc_state->wm.skl.plane_ddb_y[plane_id]; |
---|
5053 | 5696 | |
---|
5054 | 5697 | for (level = 0; level <= max_level; level++) { |
---|
| 5698 | + const struct skl_wm_level *wm_level; |
---|
| 5699 | + |
---|
| 5700 | + wm_level = skl_plane_wm_level(crtc_state, plane_id, level); |
---|
| 5701 | + |
---|
5055 | 5702 | skl_write_wm_level(dev_priv, CUR_WM(pipe, level), |
---|
5056 | | - &wm->wm[level]); |
---|
| 5703 | + wm_level); |
---|
5057 | 5704 | } |
---|
5058 | 5705 | skl_write_wm_level(dev_priv, CUR_WM_TRANS(pipe), &wm->trans_wm); |
---|
5059 | 5706 | |
---|
5060 | | - skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), |
---|
5061 | | - &ddb->plane[pipe][PLANE_CURSOR]); |
---|
| 5707 | + skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), ddb); |
---|
5062 | 5708 | } |
---|
5063 | 5709 | |
---|
5064 | 5710 | bool skl_wm_level_equals(const struct skl_wm_level *l1, |
---|
5065 | 5711 | const struct skl_wm_level *l2) |
---|
5066 | 5712 | { |
---|
5067 | | - if (l1->plane_en != l2->plane_en) |
---|
5068 | | - return false; |
---|
5069 | | - |
---|
5070 | | - /* If both planes aren't enabled, the rest shouldn't matter */ |
---|
5071 | | - if (!l1->plane_en) |
---|
5072 | | - return true; |
---|
5073 | | - |
---|
5074 | | - return (l1->plane_res_l == l2->plane_res_l && |
---|
5075 | | - l1->plane_res_b == l2->plane_res_b); |
---|
| 5713 | + return l1->plane_en == l2->plane_en && |
---|
| 5714 | + l1->ignore_lines == l2->ignore_lines && |
---|
| 5715 | + l1->plane_res_l == l2->plane_res_l && |
---|
| 5716 | + l1->plane_res_b == l2->plane_res_b; |
---|
5076 | 5717 | } |
---|
5077 | 5718 | |
---|
5078 | | -static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a, |
---|
5079 | | - const struct skl_ddb_entry *b) |
---|
| 5719 | +static bool skl_plane_wm_equals(struct drm_i915_private *dev_priv, |
---|
| 5720 | + const struct skl_plane_wm *wm1, |
---|
| 5721 | + const struct skl_plane_wm *wm2) |
---|
| 5722 | +{ |
---|
| 5723 | + int level, max_level = ilk_wm_max_level(dev_priv); |
---|
| 5724 | + |
---|
| 5725 | + for (level = 0; level <= max_level; level++) { |
---|
| 5726 | + /* |
---|
| 5727 | + * We don't check uv_wm as the hardware doesn't actually |
---|
| 5728 | + * use it. It only gets used for calculating the required |
---|
| 5729 | + * ddb allocation. |
---|
| 5730 | + */ |
---|
| 5731 | + if (!skl_wm_level_equals(&wm1->wm[level], &wm2->wm[level])) |
---|
| 5732 | + return false; |
---|
| 5733 | + } |
---|
| 5734 | + |
---|
| 5735 | + return skl_wm_level_equals(&wm1->trans_wm, &wm2->trans_wm); |
---|
| 5736 | +} |
---|
| 5737 | + |
---|
| 5738 | +static bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a, |
---|
| 5739 | + const struct skl_ddb_entry *b) |
---|
5080 | 5740 | { |
---|
5081 | 5741 | return a->start < b->end && b->start < a->end; |
---|
5082 | 5742 | } |
---|
5083 | 5743 | |
---|
5084 | | -bool skl_ddb_allocation_overlaps(struct drm_i915_private *dev_priv, |
---|
5085 | | - const struct skl_ddb_entry **entries, |
---|
5086 | | - const struct skl_ddb_entry *ddb, |
---|
5087 | | - int ignore) |
---|
| 5744 | +bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb, |
---|
| 5745 | + const struct skl_ddb_entry *entries, |
---|
| 5746 | + int num_entries, int ignore_idx) |
---|
5088 | 5747 | { |
---|
5089 | | - enum pipe pipe; |
---|
| 5748 | + int i; |
---|
5090 | 5749 | |
---|
5091 | | - for_each_pipe(dev_priv, pipe) { |
---|
5092 | | - if (pipe != ignore && entries[pipe] && |
---|
5093 | | - skl_ddb_entries_overlap(ddb, entries[pipe])) |
---|
| 5750 | + for (i = 0; i < num_entries; i++) { |
---|
| 5751 | + if (i != ignore_idx && |
---|
| 5752 | + skl_ddb_entries_overlap(ddb, &entries[i])) |
---|
5094 | 5753 | return true; |
---|
5095 | 5754 | } |
---|
5096 | 5755 | |
---|
5097 | 5756 | return false; |
---|
5098 | 5757 | } |
---|
5099 | 5758 | |
---|
5100 | | -static int skl_update_pipe_wm(struct drm_crtc_state *cstate, |
---|
5101 | | - const struct skl_pipe_wm *old_pipe_wm, |
---|
5102 | | - struct skl_pipe_wm *pipe_wm, /* out */ |
---|
5103 | | - struct skl_ddb_allocation *ddb, /* out */ |
---|
5104 | | - bool *changed /* out */) |
---|
5105 | | -{ |
---|
5106 | | - struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate); |
---|
5107 | | - int ret; |
---|
5108 | | - |
---|
5109 | | - ret = skl_build_pipe_wm(intel_cstate, ddb, pipe_wm); |
---|
5110 | | - if (ret) |
---|
5111 | | - return ret; |
---|
5112 | | - |
---|
5113 | | - if (!memcmp(old_pipe_wm, pipe_wm, sizeof(*pipe_wm))) |
---|
5114 | | - *changed = false; |
---|
5115 | | - else |
---|
5116 | | - *changed = true; |
---|
5117 | | - |
---|
5118 | | - return 0; |
---|
5119 | | -} |
---|
5120 | | - |
---|
5121 | | -static uint32_t |
---|
5122 | | -pipes_modified(struct drm_atomic_state *state) |
---|
5123 | | -{ |
---|
5124 | | - struct drm_crtc *crtc; |
---|
5125 | | - struct drm_crtc_state *cstate; |
---|
5126 | | - uint32_t i, ret = 0; |
---|
5127 | | - |
---|
5128 | | - for_each_new_crtc_in_state(state, crtc, cstate, i) |
---|
5129 | | - ret |= drm_crtc_mask(crtc); |
---|
5130 | | - |
---|
5131 | | - return ret; |
---|
5132 | | -} |
---|
5133 | | - |
---|
5134 | 5759 | static int |
---|
5135 | | -skl_ddb_add_affected_planes(struct intel_crtc_state *cstate) |
---|
| 5760 | +skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state, |
---|
| 5761 | + struct intel_crtc_state *new_crtc_state) |
---|
5136 | 5762 | { |
---|
5137 | | - struct drm_atomic_state *state = cstate->base.state; |
---|
5138 | | - struct drm_device *dev = state->dev; |
---|
5139 | | - struct drm_crtc *crtc = cstate->base.crtc; |
---|
5140 | | - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
---|
5141 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
5142 | | - struct intel_atomic_state *intel_state = to_intel_atomic_state(state); |
---|
5143 | | - struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; |
---|
5144 | | - struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; |
---|
5145 | | - struct drm_plane_state *plane_state; |
---|
5146 | | - struct drm_plane *plane; |
---|
5147 | | - enum pipe pipe = intel_crtc->pipe; |
---|
| 5763 | + struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->uapi.state); |
---|
| 5764 | + struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); |
---|
| 5765 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 5766 | + struct intel_plane *plane; |
---|
5148 | 5767 | |
---|
5149 | | - drm_for_each_plane_mask(plane, dev, cstate->base.plane_mask) { |
---|
5150 | | - enum plane_id plane_id = to_intel_plane(plane)->id; |
---|
| 5768 | + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { |
---|
| 5769 | + struct intel_plane_state *plane_state; |
---|
| 5770 | + enum plane_id plane_id = plane->id; |
---|
5151 | 5771 | |
---|
5152 | | - if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id], |
---|
5153 | | - &new_ddb->plane[pipe][plane_id]) && |
---|
5154 | | - skl_ddb_entry_equal(&cur_ddb->uv_plane[pipe][plane_id], |
---|
5155 | | - &new_ddb->uv_plane[pipe][plane_id])) |
---|
| 5772 | + if (skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_y[plane_id], |
---|
| 5773 | + &new_crtc_state->wm.skl.plane_ddb_y[plane_id]) && |
---|
| 5774 | + skl_ddb_entry_equal(&old_crtc_state->wm.skl.plane_ddb_uv[plane_id], |
---|
| 5775 | + &new_crtc_state->wm.skl.plane_ddb_uv[plane_id])) |
---|
5156 | 5776 | continue; |
---|
5157 | 5777 | |
---|
5158 | | - plane_state = drm_atomic_get_plane_state(state, plane); |
---|
| 5778 | + plane_state = intel_atomic_get_plane_state(state, plane); |
---|
5159 | 5779 | if (IS_ERR(plane_state)) |
---|
5160 | 5780 | return PTR_ERR(plane_state); |
---|
| 5781 | + |
---|
| 5782 | + new_crtc_state->update_planes |= BIT(plane_id); |
---|
5161 | 5783 | } |
---|
5162 | 5784 | |
---|
5163 | 5785 | return 0; |
---|
5164 | 5786 | } |
---|
5165 | 5787 | |
---|
5166 | 5788 | static int |
---|
5167 | | -skl_compute_ddb(struct drm_atomic_state *state) |
---|
| 5789 | +skl_compute_ddb(struct intel_atomic_state *state) |
---|
5168 | 5790 | { |
---|
5169 | | - const struct drm_i915_private *dev_priv = to_i915(state->dev); |
---|
5170 | | - struct intel_atomic_state *intel_state = to_intel_atomic_state(state); |
---|
5171 | | - struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb; |
---|
| 5791 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
| 5792 | + const struct intel_dbuf_state *old_dbuf_state; |
---|
| 5793 | + const struct intel_dbuf_state *new_dbuf_state; |
---|
| 5794 | + const struct intel_crtc_state *old_crtc_state; |
---|
| 5795 | + struct intel_crtc_state *new_crtc_state; |
---|
5172 | 5796 | struct intel_crtc *crtc; |
---|
5173 | | - struct intel_crtc_state *cstate; |
---|
5174 | 5797 | int ret, i; |
---|
5175 | 5798 | |
---|
5176 | | - memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb)); |
---|
5177 | | - |
---|
5178 | | - for_each_new_intel_crtc_in_state(intel_state, crtc, cstate, i) { |
---|
5179 | | - ret = skl_allocate_pipe_ddb(cstate, ddb); |
---|
| 5799 | + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, |
---|
| 5800 | + new_crtc_state, i) { |
---|
| 5801 | + ret = skl_allocate_pipe_ddb(new_crtc_state); |
---|
5180 | 5802 | if (ret) |
---|
5181 | 5803 | return ret; |
---|
5182 | 5804 | |
---|
5183 | | - ret = skl_ddb_add_affected_planes(cstate); |
---|
| 5805 | + ret = skl_ddb_add_affected_planes(old_crtc_state, |
---|
| 5806 | + new_crtc_state); |
---|
5184 | 5807 | if (ret) |
---|
5185 | 5808 | return ret; |
---|
5186 | 5809 | } |
---|
5187 | 5810 | |
---|
| 5811 | + old_dbuf_state = intel_atomic_get_old_dbuf_state(state); |
---|
| 5812 | + new_dbuf_state = intel_atomic_get_new_dbuf_state(state); |
---|
| 5813 | + |
---|
| 5814 | + if (new_dbuf_state && |
---|
| 5815 | + new_dbuf_state->enabled_slices != old_dbuf_state->enabled_slices) |
---|
| 5816 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 5817 | + "Enabled dbuf slices 0x%x -> 0x%x (out of %d dbuf slices)\n", |
---|
| 5818 | + old_dbuf_state->enabled_slices, |
---|
| 5819 | + new_dbuf_state->enabled_slices, |
---|
| 5820 | + INTEL_INFO(dev_priv)->num_supported_dbuf_slices); |
---|
| 5821 | + |
---|
5188 | 5822 | return 0; |
---|
5189 | 5823 | } |
---|
5190 | 5824 | |
---|
5191 | | -static void |
---|
5192 | | -skl_copy_ddb_for_pipe(struct skl_ddb_values *dst, |
---|
5193 | | - struct skl_ddb_values *src, |
---|
5194 | | - enum pipe pipe) |
---|
| 5825 | +static char enast(bool enable) |
---|
5195 | 5826 | { |
---|
5196 | | - memcpy(dst->ddb.uv_plane[pipe], src->ddb.uv_plane[pipe], |
---|
5197 | | - sizeof(dst->ddb.uv_plane[pipe])); |
---|
5198 | | - memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe], |
---|
5199 | | - sizeof(dst->ddb.plane[pipe])); |
---|
| 5827 | + return enable ? '*' : ' '; |
---|
5200 | 5828 | } |
---|
5201 | 5829 | |
---|
5202 | 5830 | static void |
---|
5203 | | -skl_print_wm_changes(const struct drm_atomic_state *state) |
---|
| 5831 | +skl_print_wm_changes(struct intel_atomic_state *state) |
---|
5204 | 5832 | { |
---|
5205 | | - const struct drm_device *dev = state->dev; |
---|
5206 | | - const struct drm_i915_private *dev_priv = to_i915(dev); |
---|
5207 | | - const struct intel_atomic_state *intel_state = |
---|
5208 | | - to_intel_atomic_state(state); |
---|
5209 | | - const struct drm_crtc *crtc; |
---|
5210 | | - const struct drm_crtc_state *cstate; |
---|
5211 | | - const struct intel_plane *intel_plane; |
---|
5212 | | - const struct skl_ddb_allocation *old_ddb = &dev_priv->wm.skl_hw.ddb; |
---|
5213 | | - const struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; |
---|
| 5833 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
| 5834 | + const struct intel_crtc_state *old_crtc_state; |
---|
| 5835 | + const struct intel_crtc_state *new_crtc_state; |
---|
| 5836 | + struct intel_plane *plane; |
---|
| 5837 | + struct intel_crtc *crtc; |
---|
5214 | 5838 | int i; |
---|
5215 | 5839 | |
---|
5216 | | - for_each_new_crtc_in_state(state, crtc, cstate, i) { |
---|
5217 | | - const struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
---|
5218 | | - enum pipe pipe = intel_crtc->pipe; |
---|
| 5840 | + if (!drm_debug_enabled(DRM_UT_KMS)) |
---|
| 5841 | + return; |
---|
5219 | 5842 | |
---|
5220 | | - for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
---|
5221 | | - enum plane_id plane_id = intel_plane->id; |
---|
| 5843 | + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, |
---|
| 5844 | + new_crtc_state, i) { |
---|
| 5845 | + const struct skl_pipe_wm *old_pipe_wm, *new_pipe_wm; |
---|
| 5846 | + |
---|
| 5847 | + old_pipe_wm = &old_crtc_state->wm.skl.optimal; |
---|
| 5848 | + new_pipe_wm = &new_crtc_state->wm.skl.optimal; |
---|
| 5849 | + |
---|
| 5850 | + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { |
---|
| 5851 | + enum plane_id plane_id = plane->id; |
---|
5222 | 5852 | const struct skl_ddb_entry *old, *new; |
---|
5223 | 5853 | |
---|
5224 | | - old = &old_ddb->plane[pipe][plane_id]; |
---|
5225 | | - new = &new_ddb->plane[pipe][plane_id]; |
---|
| 5854 | + old = &old_crtc_state->wm.skl.plane_ddb_y[plane_id]; |
---|
| 5855 | + new = &new_crtc_state->wm.skl.plane_ddb_y[plane_id]; |
---|
5226 | 5856 | |
---|
5227 | 5857 | if (skl_ddb_entry_equal(old, new)) |
---|
5228 | 5858 | continue; |
---|
5229 | 5859 | |
---|
5230 | | - DRM_DEBUG_ATOMIC("[PLANE:%d:%s] ddb (%d - %d) -> (%d - %d)\n", |
---|
5231 | | - intel_plane->base.base.id, |
---|
5232 | | - intel_plane->base.name, |
---|
5233 | | - old->start, old->end, |
---|
5234 | | - new->start, new->end); |
---|
| 5860 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 5861 | + "[PLANE:%d:%s] ddb (%4d - %4d) -> (%4d - %4d), size %4d -> %4d\n", |
---|
| 5862 | + plane->base.base.id, plane->base.name, |
---|
| 5863 | + old->start, old->end, new->start, new->end, |
---|
| 5864 | + skl_ddb_entry_size(old), skl_ddb_entry_size(new)); |
---|
| 5865 | + } |
---|
| 5866 | + |
---|
| 5867 | + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { |
---|
| 5868 | + enum plane_id plane_id = plane->id; |
---|
| 5869 | + const struct skl_plane_wm *old_wm, *new_wm; |
---|
| 5870 | + |
---|
| 5871 | + old_wm = &old_pipe_wm->planes[plane_id]; |
---|
| 5872 | + new_wm = &new_pipe_wm->planes[plane_id]; |
---|
| 5873 | + |
---|
| 5874 | + if (skl_plane_wm_equals(dev_priv, old_wm, new_wm)) |
---|
| 5875 | + continue; |
---|
| 5876 | + |
---|
| 5877 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 5878 | + "[PLANE:%d:%s] level %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm" |
---|
| 5879 | + " -> %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm\n", |
---|
| 5880 | + plane->base.base.id, plane->base.name, |
---|
| 5881 | + enast(old_wm->wm[0].plane_en), enast(old_wm->wm[1].plane_en), |
---|
| 5882 | + enast(old_wm->wm[2].plane_en), enast(old_wm->wm[3].plane_en), |
---|
| 5883 | + enast(old_wm->wm[4].plane_en), enast(old_wm->wm[5].plane_en), |
---|
| 5884 | + enast(old_wm->wm[6].plane_en), enast(old_wm->wm[7].plane_en), |
---|
| 5885 | + enast(old_wm->trans_wm.plane_en), |
---|
| 5886 | + enast(old_wm->sagv_wm0.plane_en), |
---|
| 5887 | + enast(new_wm->wm[0].plane_en), enast(new_wm->wm[1].plane_en), |
---|
| 5888 | + enast(new_wm->wm[2].plane_en), enast(new_wm->wm[3].plane_en), |
---|
| 5889 | + enast(new_wm->wm[4].plane_en), enast(new_wm->wm[5].plane_en), |
---|
| 5890 | + enast(new_wm->wm[6].plane_en), enast(new_wm->wm[7].plane_en), |
---|
| 5891 | + enast(new_wm->trans_wm.plane_en), |
---|
| 5892 | + enast(new_wm->sagv_wm0.plane_en)); |
---|
| 5893 | + |
---|
| 5894 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 5895 | + "[PLANE:%d:%s] lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d" |
---|
| 5896 | + " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d\n", |
---|
| 5897 | + plane->base.base.id, plane->base.name, |
---|
| 5898 | + enast(old_wm->wm[0].ignore_lines), old_wm->wm[0].plane_res_l, |
---|
| 5899 | + enast(old_wm->wm[1].ignore_lines), old_wm->wm[1].plane_res_l, |
---|
| 5900 | + enast(old_wm->wm[2].ignore_lines), old_wm->wm[2].plane_res_l, |
---|
| 5901 | + enast(old_wm->wm[3].ignore_lines), old_wm->wm[3].plane_res_l, |
---|
| 5902 | + enast(old_wm->wm[4].ignore_lines), old_wm->wm[4].plane_res_l, |
---|
| 5903 | + enast(old_wm->wm[5].ignore_lines), old_wm->wm[5].plane_res_l, |
---|
| 5904 | + enast(old_wm->wm[6].ignore_lines), old_wm->wm[6].plane_res_l, |
---|
| 5905 | + enast(old_wm->wm[7].ignore_lines), old_wm->wm[7].plane_res_l, |
---|
| 5906 | + enast(old_wm->trans_wm.ignore_lines), old_wm->trans_wm.plane_res_l, |
---|
| 5907 | + enast(old_wm->sagv_wm0.ignore_lines), old_wm->sagv_wm0.plane_res_l, |
---|
| 5908 | + |
---|
| 5909 | + enast(new_wm->wm[0].ignore_lines), new_wm->wm[0].plane_res_l, |
---|
| 5910 | + enast(new_wm->wm[1].ignore_lines), new_wm->wm[1].plane_res_l, |
---|
| 5911 | + enast(new_wm->wm[2].ignore_lines), new_wm->wm[2].plane_res_l, |
---|
| 5912 | + enast(new_wm->wm[3].ignore_lines), new_wm->wm[3].plane_res_l, |
---|
| 5913 | + enast(new_wm->wm[4].ignore_lines), new_wm->wm[4].plane_res_l, |
---|
| 5914 | + enast(new_wm->wm[5].ignore_lines), new_wm->wm[5].plane_res_l, |
---|
| 5915 | + enast(new_wm->wm[6].ignore_lines), new_wm->wm[6].plane_res_l, |
---|
| 5916 | + enast(new_wm->wm[7].ignore_lines), new_wm->wm[7].plane_res_l, |
---|
| 5917 | + enast(new_wm->trans_wm.ignore_lines), new_wm->trans_wm.plane_res_l, |
---|
| 5918 | + enast(new_wm->sagv_wm0.ignore_lines), new_wm->sagv_wm0.plane_res_l); |
---|
| 5919 | + |
---|
| 5920 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 5921 | + "[PLANE:%d:%s] blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d" |
---|
| 5922 | + " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\n", |
---|
| 5923 | + plane->base.base.id, plane->base.name, |
---|
| 5924 | + old_wm->wm[0].plane_res_b, old_wm->wm[1].plane_res_b, |
---|
| 5925 | + old_wm->wm[2].plane_res_b, old_wm->wm[3].plane_res_b, |
---|
| 5926 | + old_wm->wm[4].plane_res_b, old_wm->wm[5].plane_res_b, |
---|
| 5927 | + old_wm->wm[6].plane_res_b, old_wm->wm[7].plane_res_b, |
---|
| 5928 | + old_wm->trans_wm.plane_res_b, |
---|
| 5929 | + old_wm->sagv_wm0.plane_res_b, |
---|
| 5930 | + new_wm->wm[0].plane_res_b, new_wm->wm[1].plane_res_b, |
---|
| 5931 | + new_wm->wm[2].plane_res_b, new_wm->wm[3].plane_res_b, |
---|
| 5932 | + new_wm->wm[4].plane_res_b, new_wm->wm[5].plane_res_b, |
---|
| 5933 | + new_wm->wm[6].plane_res_b, new_wm->wm[7].plane_res_b, |
---|
| 5934 | + new_wm->trans_wm.plane_res_b, |
---|
| 5935 | + new_wm->sagv_wm0.plane_res_b); |
---|
| 5936 | + |
---|
| 5937 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 5938 | + "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d" |
---|
| 5939 | + " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\n", |
---|
| 5940 | + plane->base.base.id, plane->base.name, |
---|
| 5941 | + old_wm->wm[0].min_ddb_alloc, old_wm->wm[1].min_ddb_alloc, |
---|
| 5942 | + old_wm->wm[2].min_ddb_alloc, old_wm->wm[3].min_ddb_alloc, |
---|
| 5943 | + old_wm->wm[4].min_ddb_alloc, old_wm->wm[5].min_ddb_alloc, |
---|
| 5944 | + old_wm->wm[6].min_ddb_alloc, old_wm->wm[7].min_ddb_alloc, |
---|
| 5945 | + old_wm->trans_wm.min_ddb_alloc, |
---|
| 5946 | + old_wm->sagv_wm0.min_ddb_alloc, |
---|
| 5947 | + new_wm->wm[0].min_ddb_alloc, new_wm->wm[1].min_ddb_alloc, |
---|
| 5948 | + new_wm->wm[2].min_ddb_alloc, new_wm->wm[3].min_ddb_alloc, |
---|
| 5949 | + new_wm->wm[4].min_ddb_alloc, new_wm->wm[5].min_ddb_alloc, |
---|
| 5950 | + new_wm->wm[6].min_ddb_alloc, new_wm->wm[7].min_ddb_alloc, |
---|
| 5951 | + new_wm->trans_wm.min_ddb_alloc, |
---|
| 5952 | + new_wm->sagv_wm0.min_ddb_alloc); |
---|
5235 | 5953 | } |
---|
5236 | 5954 | } |
---|
5237 | 5955 | } |
---|
5238 | 5956 | |
---|
5239 | | -static int |
---|
5240 | | -skl_ddb_add_affected_pipes(struct drm_atomic_state *state, bool *changed) |
---|
| 5957 | +static int intel_add_affected_pipes(struct intel_atomic_state *state, |
---|
| 5958 | + u8 pipe_mask) |
---|
5241 | 5959 | { |
---|
5242 | | - struct drm_device *dev = state->dev; |
---|
5243 | | - const struct drm_i915_private *dev_priv = to_i915(dev); |
---|
5244 | | - const struct drm_crtc *crtc; |
---|
5245 | | - const struct drm_crtc_state *cstate; |
---|
5246 | | - struct intel_crtc *intel_crtc; |
---|
5247 | | - struct intel_atomic_state *intel_state = to_intel_atomic_state(state); |
---|
5248 | | - uint32_t realloc_pipes = pipes_modified(state); |
---|
5249 | | - int ret, i; |
---|
| 5960 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
| 5961 | + struct intel_crtc *crtc; |
---|
5250 | 5962 | |
---|
5251 | | - /* |
---|
5252 | | - * When we distrust bios wm we always need to recompute to set the |
---|
5253 | | - * expected DDB allocations for each CRTC. |
---|
5254 | | - */ |
---|
5255 | | - if (dev_priv->wm.distrust_bios_wm) |
---|
5256 | | - (*changed) = true; |
---|
| 5963 | + for_each_intel_crtc(&dev_priv->drm, crtc) { |
---|
| 5964 | + struct intel_crtc_state *crtc_state; |
---|
5257 | 5965 | |
---|
5258 | | - /* |
---|
5259 | | - * If this transaction isn't actually touching any CRTC's, don't |
---|
5260 | | - * bother with watermark calculation. Note that if we pass this |
---|
5261 | | - * test, we're guaranteed to hold at least one CRTC state mutex, |
---|
5262 | | - * which means we can safely use values like dev_priv->active_crtcs |
---|
5263 | | - * since any racing commits that want to update them would need to |
---|
5264 | | - * hold _all_ CRTC state mutexes. |
---|
5265 | | - */ |
---|
5266 | | - for_each_new_crtc_in_state(state, crtc, cstate, i) |
---|
5267 | | - (*changed) = true; |
---|
| 5966 | + if ((pipe_mask & BIT(crtc->pipe)) == 0) |
---|
| 5967 | + continue; |
---|
5268 | 5968 | |
---|
5269 | | - if (!*changed) |
---|
5270 | | - return 0; |
---|
5271 | | - |
---|
5272 | | - /* |
---|
5273 | | - * If this is our first atomic update following hardware readout, |
---|
5274 | | - * we can't trust the DDB that the BIOS programmed for us. Let's |
---|
5275 | | - * pretend that all pipes switched active status so that we'll |
---|
5276 | | - * ensure a full DDB recompute. |
---|
5277 | | - */ |
---|
5278 | | - if (dev_priv->wm.distrust_bios_wm) { |
---|
5279 | | - ret = drm_modeset_lock(&dev->mode_config.connection_mutex, |
---|
5280 | | - state->acquire_ctx); |
---|
5281 | | - if (ret) |
---|
5282 | | - return ret; |
---|
5283 | | - |
---|
5284 | | - intel_state->active_pipe_changes = ~0; |
---|
5285 | | - |
---|
5286 | | - /* |
---|
5287 | | - * We usually only initialize intel_state->active_crtcs if we |
---|
5288 | | - * we're doing a modeset; make sure this field is always |
---|
5289 | | - * initialized during the sanitization process that happens |
---|
5290 | | - * on the first commit too. |
---|
5291 | | - */ |
---|
5292 | | - if (!intel_state->modeset) |
---|
5293 | | - intel_state->active_crtcs = dev_priv->active_crtcs; |
---|
5294 | | - } |
---|
5295 | | - |
---|
5296 | | - /* |
---|
5297 | | - * If the modeset changes which CRTC's are active, we need to |
---|
5298 | | - * recompute the DDB allocation for *all* active pipes, even |
---|
5299 | | - * those that weren't otherwise being modified in any way by this |
---|
5300 | | - * atomic commit. Due to the shrinking of the per-pipe allocations |
---|
5301 | | - * when new active CRTC's are added, it's possible for a pipe that |
---|
5302 | | - * we were already using and aren't changing at all here to suddenly |
---|
5303 | | - * become invalid if its DDB needs exceeds its new allocation. |
---|
5304 | | - * |
---|
5305 | | - * Note that if we wind up doing a full DDB recompute, we can't let |
---|
5306 | | - * any other display updates race with this transaction, so we need |
---|
5307 | | - * to grab the lock on *all* CRTC's. |
---|
5308 | | - */ |
---|
5309 | | - if (intel_state->active_pipe_changes) { |
---|
5310 | | - realloc_pipes = ~0; |
---|
5311 | | - intel_state->wm_results.dirty_pipes = ~0; |
---|
5312 | | - } |
---|
5313 | | - |
---|
5314 | | - /* |
---|
5315 | | - * We're not recomputing for the pipes not included in the commit, so |
---|
5316 | | - * make sure we start with the current state. |
---|
5317 | | - */ |
---|
5318 | | - for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) { |
---|
5319 | | - struct intel_crtc_state *cstate; |
---|
5320 | | - |
---|
5321 | | - cstate = intel_atomic_get_crtc_state(state, intel_crtc); |
---|
5322 | | - if (IS_ERR(cstate)) |
---|
5323 | | - return PTR_ERR(cstate); |
---|
| 5969 | + crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); |
---|
| 5970 | + if (IS_ERR(crtc_state)) |
---|
| 5971 | + return PTR_ERR(crtc_state); |
---|
5324 | 5972 | } |
---|
5325 | 5973 | |
---|
5326 | 5974 | return 0; |
---|
5327 | 5975 | } |
---|
5328 | 5976 | |
---|
5329 | 5977 | static int |
---|
5330 | | -skl_compute_wm(struct drm_atomic_state *state) |
---|
| 5978 | +skl_ddb_add_affected_pipes(struct intel_atomic_state *state) |
---|
5331 | 5979 | { |
---|
5332 | | - struct drm_crtc *crtc; |
---|
5333 | | - struct drm_crtc_state *cstate; |
---|
5334 | | - struct intel_atomic_state *intel_state = to_intel_atomic_state(state); |
---|
5335 | | - struct skl_ddb_values *results = &intel_state->wm_results; |
---|
5336 | | - struct skl_pipe_wm *pipe_wm; |
---|
5337 | | - bool changed = false; |
---|
| 5980 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
| 5981 | + struct intel_crtc_state *crtc_state; |
---|
| 5982 | + struct intel_crtc *crtc; |
---|
| 5983 | + int i, ret; |
---|
| 5984 | + |
---|
| 5985 | + if (dev_priv->wm.distrust_bios_wm) { |
---|
| 5986 | + /* |
---|
| 5987 | + * skl_ddb_get_pipe_allocation_limits() currently requires |
---|
| 5988 | + * all active pipes to be included in the state so that |
---|
| 5989 | + * it can redistribute the dbuf among them, and it really |
---|
| 5990 | + * wants to recompute things when distrust_bios_wm is set |
---|
| 5991 | + * so we add all the pipes to the state. |
---|
| 5992 | + */ |
---|
| 5993 | + ret = intel_add_affected_pipes(state, ~0); |
---|
| 5994 | + if (ret) |
---|
| 5995 | + return ret; |
---|
| 5996 | + } |
---|
| 5997 | + |
---|
| 5998 | + for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { |
---|
| 5999 | + struct intel_dbuf_state *new_dbuf_state; |
---|
| 6000 | + const struct intel_dbuf_state *old_dbuf_state; |
---|
| 6001 | + |
---|
| 6002 | + new_dbuf_state = intel_atomic_get_dbuf_state(state); |
---|
| 6003 | + if (IS_ERR(new_dbuf_state)) |
---|
| 6004 | + return PTR_ERR(new_dbuf_state); |
---|
| 6005 | + |
---|
| 6006 | + old_dbuf_state = intel_atomic_get_old_dbuf_state(state); |
---|
| 6007 | + |
---|
| 6008 | + new_dbuf_state->active_pipes = |
---|
| 6009 | + intel_calc_active_pipes(state, old_dbuf_state->active_pipes); |
---|
| 6010 | + |
---|
| 6011 | + if (old_dbuf_state->active_pipes == new_dbuf_state->active_pipes) |
---|
| 6012 | + break; |
---|
| 6013 | + |
---|
| 6014 | + ret = intel_atomic_lock_global_state(&new_dbuf_state->base); |
---|
| 6015 | + if (ret) |
---|
| 6016 | + return ret; |
---|
| 6017 | + |
---|
| 6018 | + /* |
---|
| 6019 | + * skl_ddb_get_pipe_allocation_limits() currently requires |
---|
| 6020 | + * all active pipes to be included in the state so that |
---|
| 6021 | + * it can redistribute the dbuf among them. |
---|
| 6022 | + */ |
---|
| 6023 | + ret = intel_add_affected_pipes(state, |
---|
| 6024 | + new_dbuf_state->active_pipes); |
---|
| 6025 | + if (ret) |
---|
| 6026 | + return ret; |
---|
| 6027 | + |
---|
| 6028 | + break; |
---|
| 6029 | + } |
---|
| 6030 | + |
---|
| 6031 | + return 0; |
---|
| 6032 | +} |
---|
| 6033 | + |
---|
| 6034 | +/* |
---|
| 6035 | + * To make sure the cursor watermark registers are always consistent |
---|
| 6036 | + * with our computed state the following scenario needs special |
---|
| 6037 | + * treatment: |
---|
| 6038 | + * |
---|
| 6039 | + * 1. enable cursor |
---|
| 6040 | + * 2. move cursor entirely offscreen |
---|
| 6041 | + * 3. disable cursor |
---|
| 6042 | + * |
---|
| 6043 | + * Step 2. does call .disable_plane() but does not zero the watermarks |
---|
| 6044 | + * (since we consider an offscreen cursor still active for the purposes |
---|
| 6045 | + * of watermarks). Step 3. would not normally call .disable_plane() |
---|
| 6046 | + * because the actual plane visibility isn't changing, and we don't |
---|
| 6047 | + * deallocate the cursor ddb until the pipe gets disabled. So we must |
---|
| 6048 | + * force step 3. to call .disable_plane() to update the watermark |
---|
| 6049 | + * registers properly. |
---|
| 6050 | + * |
---|
| 6051 | + * Other planes do not suffer from this issues as their watermarks are |
---|
| 6052 | + * calculated based on the actual plane visibility. The only time this |
---|
| 6053 | + * can trigger for the other planes is during the initial readout as the |
---|
| 6054 | + * default value of the watermarks registers is not zero. |
---|
| 6055 | + */ |
---|
| 6056 | +static int skl_wm_add_affected_planes(struct intel_atomic_state *state, |
---|
| 6057 | + struct intel_crtc *crtc) |
---|
| 6058 | +{ |
---|
| 6059 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 6060 | + const struct intel_crtc_state *old_crtc_state = |
---|
| 6061 | + intel_atomic_get_old_crtc_state(state, crtc); |
---|
| 6062 | + struct intel_crtc_state *new_crtc_state = |
---|
| 6063 | + intel_atomic_get_new_crtc_state(state, crtc); |
---|
| 6064 | + struct intel_plane *plane; |
---|
| 6065 | + |
---|
| 6066 | + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) { |
---|
| 6067 | + struct intel_plane_state *plane_state; |
---|
| 6068 | + enum plane_id plane_id = plane->id; |
---|
| 6069 | + |
---|
| 6070 | + /* |
---|
| 6071 | + * Force a full wm update for every plane on modeset. |
---|
| 6072 | + * Required because the reset value of the wm registers |
---|
| 6073 | + * is non-zero, whereas we want all disabled planes to |
---|
| 6074 | + * have zero watermarks. So if we turn off the relevant |
---|
| 6075 | + * power well the hardware state will go out of sync |
---|
| 6076 | + * with the software state. |
---|
| 6077 | + */ |
---|
| 6078 | + if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi) && |
---|
| 6079 | + skl_plane_wm_equals(dev_priv, |
---|
| 6080 | + &old_crtc_state->wm.skl.optimal.planes[plane_id], |
---|
| 6081 | + &new_crtc_state->wm.skl.optimal.planes[plane_id])) |
---|
| 6082 | + continue; |
---|
| 6083 | + |
---|
| 6084 | + plane_state = intel_atomic_get_plane_state(state, plane); |
---|
| 6085 | + if (IS_ERR(plane_state)) |
---|
| 6086 | + return PTR_ERR(plane_state); |
---|
| 6087 | + |
---|
| 6088 | + new_crtc_state->update_planes |= BIT(plane_id); |
---|
| 6089 | + } |
---|
| 6090 | + |
---|
| 6091 | + return 0; |
---|
| 6092 | +} |
---|
| 6093 | + |
---|
| 6094 | +static int |
---|
| 6095 | +skl_compute_wm(struct intel_atomic_state *state) |
---|
| 6096 | +{ |
---|
| 6097 | + struct intel_crtc *crtc; |
---|
| 6098 | + struct intel_crtc_state *new_crtc_state; |
---|
| 6099 | + struct intel_crtc_state *old_crtc_state; |
---|
5338 | 6100 | int ret, i; |
---|
5339 | 6101 | |
---|
5340 | | - /* Clear all dirty flags */ |
---|
5341 | | - results->dirty_pipes = 0; |
---|
5342 | | - |
---|
5343 | | - ret = skl_ddb_add_affected_pipes(state, &changed); |
---|
5344 | | - if (ret || !changed) |
---|
5345 | | - return ret; |
---|
5346 | | - |
---|
5347 | | - ret = skl_compute_ddb(state); |
---|
| 6102 | + ret = skl_ddb_add_affected_pipes(state); |
---|
5348 | 6103 | if (ret) |
---|
5349 | 6104 | return ret; |
---|
5350 | 6105 | |
---|
5351 | 6106 | /* |
---|
5352 | 6107 | * Calculate WM's for all pipes that are part of this transaction. |
---|
5353 | | - * Note that the DDB allocation above may have added more CRTC's that |
---|
5354 | | - * weren't otherwise being modified (and set bits in dirty_pipes) if |
---|
5355 | | - * pipe allocations had to change. |
---|
5356 | | - * |
---|
5357 | | - * FIXME: Now that we're doing this in the atomic check phase, we |
---|
5358 | | - * should allow skl_update_pipe_wm() to return failure in cases where |
---|
5359 | | - * no suitable watermark values can be found. |
---|
| 6108 | + * Note that skl_ddb_add_affected_pipes may have added more CRTC's that |
---|
| 6109 | + * weren't otherwise being modified if pipe allocations had to change. |
---|
5360 | 6110 | */ |
---|
5361 | | - for_each_new_crtc_in_state(state, crtc, cstate, i) { |
---|
5362 | | - struct intel_crtc_state *intel_cstate = |
---|
5363 | | - to_intel_crtc_state(cstate); |
---|
5364 | | - const struct skl_pipe_wm *old_pipe_wm = |
---|
5365 | | - &to_intel_crtc_state(crtc->state)->wm.skl.optimal; |
---|
5366 | | - |
---|
5367 | | - pipe_wm = &intel_cstate->wm.skl.optimal; |
---|
5368 | | - ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm, |
---|
5369 | | - &results->ddb, &changed); |
---|
| 6111 | + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, |
---|
| 6112 | + new_crtc_state, i) { |
---|
| 6113 | + ret = skl_build_pipe_wm(new_crtc_state); |
---|
5370 | 6114 | if (ret) |
---|
5371 | 6115 | return ret; |
---|
| 6116 | + } |
---|
5372 | 6117 | |
---|
5373 | | - if (changed) |
---|
5374 | | - results->dirty_pipes |= drm_crtc_mask(crtc); |
---|
| 6118 | + ret = skl_compute_ddb(state); |
---|
| 6119 | + if (ret) |
---|
| 6120 | + return ret; |
---|
5375 | 6121 | |
---|
5376 | | - if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0) |
---|
5377 | | - /* This pipe's WM's did not change */ |
---|
5378 | | - continue; |
---|
| 6122 | + ret = intel_compute_sagv_mask(state); |
---|
| 6123 | + if (ret) |
---|
| 6124 | + return ret; |
---|
5379 | 6125 | |
---|
5380 | | - intel_cstate->update_wm_pre = true; |
---|
| 6126 | + /* |
---|
| 6127 | + * skl_compute_ddb() will have adjusted the final watermarks |
---|
| 6128 | + * based on how much ddb is available. Now we can actually |
---|
| 6129 | + * check if the final watermarks changed. |
---|
| 6130 | + */ |
---|
| 6131 | + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, |
---|
| 6132 | + new_crtc_state, i) { |
---|
| 6133 | + ret = skl_wm_add_affected_planes(state, crtc); |
---|
| 6134 | + if (ret) |
---|
| 6135 | + return ret; |
---|
5381 | 6136 | } |
---|
5382 | 6137 | |
---|
5383 | 6138 | skl_print_wm_changes(state); |
---|
.. | .. |
---|
5385 | 6140 | return 0; |
---|
5386 | 6141 | } |
---|
5387 | 6142 | |
---|
5388 | | -static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state, |
---|
5389 | | - struct intel_crtc_state *cstate) |
---|
5390 | | -{ |
---|
5391 | | - struct intel_crtc *crtc = to_intel_crtc(cstate->base.crtc); |
---|
5392 | | - struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
5393 | | - struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; |
---|
5394 | | - const struct skl_ddb_allocation *ddb = &state->wm_results.ddb; |
---|
5395 | | - enum pipe pipe = crtc->pipe; |
---|
5396 | | - enum plane_id plane_id; |
---|
5397 | | - |
---|
5398 | | - if (!(state->wm_results.dirty_pipes & drm_crtc_mask(&crtc->base))) |
---|
5399 | | - return; |
---|
5400 | | - |
---|
5401 | | - I915_WRITE(PIPE_WM_LINETIME(pipe), pipe_wm->linetime); |
---|
5402 | | - |
---|
5403 | | - for_each_plane_id_on_crtc(crtc, plane_id) { |
---|
5404 | | - if (plane_id != PLANE_CURSOR) |
---|
5405 | | - skl_write_plane_wm(crtc, &pipe_wm->planes[plane_id], |
---|
5406 | | - ddb, plane_id); |
---|
5407 | | - else |
---|
5408 | | - skl_write_cursor_wm(crtc, &pipe_wm->planes[plane_id], |
---|
5409 | | - ddb); |
---|
5410 | | - } |
---|
5411 | | -} |
---|
5412 | | - |
---|
5413 | | -static void skl_initial_wm(struct intel_atomic_state *state, |
---|
5414 | | - struct intel_crtc_state *cstate) |
---|
5415 | | -{ |
---|
5416 | | - struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); |
---|
5417 | | - struct drm_device *dev = intel_crtc->base.dev; |
---|
5418 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
5419 | | - struct skl_ddb_values *results = &state->wm_results; |
---|
5420 | | - struct skl_ddb_values *hw_vals = &dev_priv->wm.skl_hw; |
---|
5421 | | - enum pipe pipe = intel_crtc->pipe; |
---|
5422 | | - |
---|
5423 | | - if ((results->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) == 0) |
---|
5424 | | - return; |
---|
5425 | | - |
---|
5426 | | - mutex_lock(&dev_priv->wm.wm_mutex); |
---|
5427 | | - |
---|
5428 | | - if (cstate->base.active_changed) |
---|
5429 | | - skl_atomic_update_crtc_wm(state, cstate); |
---|
5430 | | - |
---|
5431 | | - skl_copy_ddb_for_pipe(hw_vals, results, pipe); |
---|
5432 | | - |
---|
5433 | | - mutex_unlock(&dev_priv->wm.wm_mutex); |
---|
5434 | | -} |
---|
5435 | | - |
---|
5436 | | -static void ilk_compute_wm_config(struct drm_device *dev, |
---|
| 6143 | +static void ilk_compute_wm_config(struct drm_i915_private *dev_priv, |
---|
5437 | 6144 | struct intel_wm_config *config) |
---|
5438 | 6145 | { |
---|
5439 | 6146 | struct intel_crtc *crtc; |
---|
5440 | 6147 | |
---|
5441 | 6148 | /* Compute the currently _active_ config */ |
---|
5442 | | - for_each_intel_crtc(dev, crtc) { |
---|
| 6149 | + for_each_intel_crtc(&dev_priv->drm, crtc) { |
---|
5443 | 6150 | const struct intel_pipe_wm *wm = &crtc->wm.active.ilk; |
---|
5444 | 6151 | |
---|
5445 | 6152 | if (!wm->pipe_enabled) |
---|
.. | .. |
---|
5453 | 6160 | |
---|
5454 | 6161 | static void ilk_program_watermarks(struct drm_i915_private *dev_priv) |
---|
5455 | 6162 | { |
---|
5456 | | - struct drm_device *dev = &dev_priv->drm; |
---|
5457 | 6163 | struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; |
---|
5458 | 6164 | struct ilk_wm_maximums max; |
---|
5459 | 6165 | struct intel_wm_config config = {}; |
---|
5460 | 6166 | struct ilk_wm_values results = {}; |
---|
5461 | 6167 | enum intel_ddb_partitioning partitioning; |
---|
5462 | 6168 | |
---|
5463 | | - ilk_compute_wm_config(dev, &config); |
---|
| 6169 | + ilk_compute_wm_config(dev_priv, &config); |
---|
5464 | 6170 | |
---|
5465 | | - ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_1_2, &max); |
---|
5466 | | - ilk_wm_merge(dev, &config, &max, &lp_wm_1_2); |
---|
| 6171 | + ilk_compute_wm_maximums(dev_priv, 1, &config, INTEL_DDB_PART_1_2, &max); |
---|
| 6172 | + ilk_wm_merge(dev_priv, &config, &max, &lp_wm_1_2); |
---|
5467 | 6173 | |
---|
5468 | 6174 | /* 5/6 split only in single pipe config on IVB+ */ |
---|
5469 | 6175 | if (INTEL_GEN(dev_priv) >= 7 && |
---|
5470 | 6176 | config.num_pipes_active == 1 && config.sprites_enabled) { |
---|
5471 | | - ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_5_6, &max); |
---|
5472 | | - ilk_wm_merge(dev, &config, &max, &lp_wm_5_6); |
---|
| 6177 | + ilk_compute_wm_maximums(dev_priv, 1, &config, INTEL_DDB_PART_5_6, &max); |
---|
| 6178 | + ilk_wm_merge(dev_priv, &config, &max, &lp_wm_5_6); |
---|
5473 | 6179 | |
---|
5474 | | - best_lp_wm = ilk_find_best_result(dev, &lp_wm_1_2, &lp_wm_5_6); |
---|
| 6180 | + best_lp_wm = ilk_find_best_result(dev_priv, &lp_wm_1_2, &lp_wm_5_6); |
---|
5475 | 6181 | } else { |
---|
5476 | 6182 | best_lp_wm = &lp_wm_1_2; |
---|
5477 | 6183 | } |
---|
.. | .. |
---|
5479 | 6185 | partitioning = (best_lp_wm == &lp_wm_1_2) ? |
---|
5480 | 6186 | INTEL_DDB_PART_1_2 : INTEL_DDB_PART_5_6; |
---|
5481 | 6187 | |
---|
5482 | | - ilk_compute_wm_results(dev, best_lp_wm, partitioning, &results); |
---|
| 6188 | + ilk_compute_wm_results(dev_priv, best_lp_wm, partitioning, &results); |
---|
5483 | 6189 | |
---|
5484 | 6190 | ilk_write_wm_values(dev_priv, &results); |
---|
5485 | 6191 | } |
---|
5486 | 6192 | |
---|
5487 | 6193 | static void ilk_initial_watermarks(struct intel_atomic_state *state, |
---|
5488 | | - struct intel_crtc_state *cstate) |
---|
| 6194 | + struct intel_crtc *crtc) |
---|
5489 | 6195 | { |
---|
5490 | | - struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev); |
---|
5491 | | - struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); |
---|
| 6196 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 6197 | + const struct intel_crtc_state *crtc_state = |
---|
| 6198 | + intel_atomic_get_new_crtc_state(state, crtc); |
---|
5492 | 6199 | |
---|
5493 | 6200 | mutex_lock(&dev_priv->wm.wm_mutex); |
---|
5494 | | - intel_crtc->wm.active.ilk = cstate->wm.ilk.intermediate; |
---|
| 6201 | + crtc->wm.active.ilk = crtc_state->wm.ilk.intermediate; |
---|
5495 | 6202 | ilk_program_watermarks(dev_priv); |
---|
5496 | 6203 | mutex_unlock(&dev_priv->wm.wm_mutex); |
---|
5497 | 6204 | } |
---|
5498 | 6205 | |
---|
5499 | 6206 | static void ilk_optimize_watermarks(struct intel_atomic_state *state, |
---|
5500 | | - struct intel_crtc_state *cstate) |
---|
| 6207 | + struct intel_crtc *crtc) |
---|
5501 | 6208 | { |
---|
5502 | | - struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev); |
---|
5503 | | - struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); |
---|
| 6209 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 6210 | + const struct intel_crtc_state *crtc_state = |
---|
| 6211 | + intel_atomic_get_new_crtc_state(state, crtc); |
---|
| 6212 | + |
---|
| 6213 | + if (!crtc_state->wm.need_postvbl_update) |
---|
| 6214 | + return; |
---|
5504 | 6215 | |
---|
5505 | 6216 | mutex_lock(&dev_priv->wm.wm_mutex); |
---|
5506 | | - if (cstate->wm.need_postvbl_update) { |
---|
5507 | | - intel_crtc->wm.active.ilk = cstate->wm.ilk.optimal; |
---|
5508 | | - ilk_program_watermarks(dev_priv); |
---|
5509 | | - } |
---|
| 6217 | + crtc->wm.active.ilk = crtc_state->wm.ilk.optimal; |
---|
| 6218 | + ilk_program_watermarks(dev_priv); |
---|
5510 | 6219 | mutex_unlock(&dev_priv->wm.wm_mutex); |
---|
5511 | 6220 | } |
---|
5512 | 6221 | |
---|
5513 | | -static inline void skl_wm_level_from_reg_val(uint32_t val, |
---|
5514 | | - struct skl_wm_level *level) |
---|
| 6222 | +static void skl_wm_level_from_reg_val(u32 val, struct skl_wm_level *level) |
---|
5515 | 6223 | { |
---|
5516 | 6224 | level->plane_en = val & PLANE_WM_EN; |
---|
| 6225 | + level->ignore_lines = val & PLANE_WM_IGNORE_LINES; |
---|
5517 | 6226 | level->plane_res_b = val & PLANE_WM_BLOCKS_MASK; |
---|
5518 | 6227 | level->plane_res_l = (val >> PLANE_WM_LINES_SHIFT) & |
---|
5519 | 6228 | PLANE_WM_LINES_MASK; |
---|
5520 | 6229 | } |
---|
5521 | 6230 | |
---|
5522 | | -void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc, |
---|
| 6231 | +void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, |
---|
5523 | 6232 | struct skl_pipe_wm *out) |
---|
5524 | 6233 | { |
---|
5525 | | - struct drm_i915_private *dev_priv = to_i915(crtc->dev); |
---|
5526 | | - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
---|
5527 | | - enum pipe pipe = intel_crtc->pipe; |
---|
| 6234 | + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
---|
| 6235 | + enum pipe pipe = crtc->pipe; |
---|
5528 | 6236 | int level, max_level; |
---|
5529 | 6237 | enum plane_id plane_id; |
---|
5530 | | - uint32_t val; |
---|
| 6238 | + u32 val; |
---|
5531 | 6239 | |
---|
5532 | 6240 | max_level = ilk_wm_max_level(dev_priv); |
---|
5533 | 6241 | |
---|
5534 | | - for_each_plane_id_on_crtc(intel_crtc, plane_id) { |
---|
| 6242 | + for_each_plane_id_on_crtc(crtc, plane_id) { |
---|
5535 | 6243 | struct skl_plane_wm *wm = &out->planes[plane_id]; |
---|
5536 | 6244 | |
---|
5537 | 6245 | for (level = 0; level <= max_level; level++) { |
---|
.. | .. |
---|
5543 | 6251 | skl_wm_level_from_reg_val(val, &wm->wm[level]); |
---|
5544 | 6252 | } |
---|
5545 | 6253 | |
---|
| 6254 | + if (INTEL_GEN(dev_priv) >= 12) |
---|
| 6255 | + wm->sagv_wm0 = wm->wm[0]; |
---|
| 6256 | + |
---|
5546 | 6257 | if (plane_id != PLANE_CURSOR) |
---|
5547 | 6258 | val = I915_READ(PLANE_WM_TRANS(pipe, plane_id)); |
---|
5548 | 6259 | else |
---|
.. | .. |
---|
5551 | 6262 | skl_wm_level_from_reg_val(val, &wm->trans_wm); |
---|
5552 | 6263 | } |
---|
5553 | 6264 | |
---|
5554 | | - if (!intel_crtc->active) |
---|
| 6265 | + if (!crtc->active) |
---|
5555 | 6266 | return; |
---|
5556 | | - |
---|
5557 | | - out->linetime = I915_READ(PIPE_WM_LINETIME(pipe)); |
---|
5558 | 6267 | } |
---|
5559 | 6268 | |
---|
5560 | | -void skl_wm_get_hw_state(struct drm_device *dev) |
---|
| 6269 | +void skl_wm_get_hw_state(struct drm_i915_private *dev_priv) |
---|
5561 | 6270 | { |
---|
5562 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
5563 | | - struct skl_ddb_values *hw = &dev_priv->wm.skl_hw; |
---|
5564 | | - struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb; |
---|
5565 | | - struct drm_crtc *crtc; |
---|
5566 | | - struct intel_crtc *intel_crtc; |
---|
5567 | | - struct intel_crtc_state *cstate; |
---|
| 6271 | + struct intel_crtc *crtc; |
---|
| 6272 | + struct intel_crtc_state *crtc_state; |
---|
5568 | 6273 | |
---|
5569 | | - skl_ddb_get_hw_state(dev_priv, ddb); |
---|
5570 | | - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
---|
5571 | | - intel_crtc = to_intel_crtc(crtc); |
---|
5572 | | - cstate = to_intel_crtc_state(crtc->state); |
---|
| 6274 | + for_each_intel_crtc(&dev_priv->drm, crtc) { |
---|
| 6275 | + crtc_state = to_intel_crtc_state(crtc->base.state); |
---|
5573 | 6276 | |
---|
5574 | | - skl_pipe_wm_get_hw_state(crtc, &cstate->wm.skl.optimal); |
---|
5575 | | - |
---|
5576 | | - if (intel_crtc->active) |
---|
5577 | | - hw->dirty_pipes |= drm_crtc_mask(crtc); |
---|
| 6277 | + skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal); |
---|
5578 | 6278 | } |
---|
5579 | 6279 | |
---|
5580 | | - if (dev_priv->active_crtcs) { |
---|
| 6280 | + if (dev_priv->active_pipes) { |
---|
5581 | 6281 | /* Fully recompute DDB on first atomic commit */ |
---|
5582 | 6282 | dev_priv->wm.distrust_bios_wm = true; |
---|
5583 | | - } else { |
---|
5584 | | - /* |
---|
5585 | | - * Easy/common case; just sanitize DDB now if everything off |
---|
5586 | | - * Keep dbuf slice info intact |
---|
5587 | | - */ |
---|
5588 | | - memset(ddb->plane, 0, sizeof(ddb->plane)); |
---|
5589 | | - memset(ddb->uv_plane, 0, sizeof(ddb->uv_plane)); |
---|
5590 | 6283 | } |
---|
5591 | 6284 | } |
---|
5592 | 6285 | |
---|
5593 | | -static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc) |
---|
| 6286 | +static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc) |
---|
5594 | 6287 | { |
---|
5595 | | - struct drm_device *dev = crtc->dev; |
---|
| 6288 | + struct drm_device *dev = crtc->base.dev; |
---|
5596 | 6289 | struct drm_i915_private *dev_priv = to_i915(dev); |
---|
5597 | 6290 | struct ilk_wm_values *hw = &dev_priv->wm.hw; |
---|
5598 | | - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
---|
5599 | | - struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
---|
5600 | | - struct intel_pipe_wm *active = &cstate->wm.ilk.optimal; |
---|
5601 | | - enum pipe pipe = intel_crtc->pipe; |
---|
| 6291 | + struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); |
---|
| 6292 | + struct intel_pipe_wm *active = &crtc_state->wm.ilk.optimal; |
---|
| 6293 | + enum pipe pipe = crtc->pipe; |
---|
5602 | 6294 | static const i915_reg_t wm0_pipe_reg[] = { |
---|
5603 | 6295 | [PIPE_A] = WM0_PIPEA_ILK, |
---|
5604 | 6296 | [PIPE_B] = WM0_PIPEB_ILK, |
---|
.. | .. |
---|
5606 | 6298 | }; |
---|
5607 | 6299 | |
---|
5608 | 6300 | hw->wm_pipe[pipe] = I915_READ(wm0_pipe_reg[pipe]); |
---|
5609 | | - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) |
---|
5610 | | - hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe)); |
---|
5611 | 6301 | |
---|
5612 | 6302 | memset(active, 0, sizeof(*active)); |
---|
5613 | 6303 | |
---|
5614 | | - active->pipe_enabled = intel_crtc->active; |
---|
| 6304 | + active->pipe_enabled = crtc->active; |
---|
5615 | 6305 | |
---|
5616 | 6306 | if (active->pipe_enabled) { |
---|
5617 | 6307 | u32 tmp = hw->wm_pipe[pipe]; |
---|
.. | .. |
---|
5626 | 6316 | active->wm[0].pri_val = (tmp & WM0_PIPE_PLANE_MASK) >> WM0_PIPE_PLANE_SHIFT; |
---|
5627 | 6317 | active->wm[0].spr_val = (tmp & WM0_PIPE_SPRITE_MASK) >> WM0_PIPE_SPRITE_SHIFT; |
---|
5628 | 6318 | active->wm[0].cur_val = tmp & WM0_PIPE_CURSOR_MASK; |
---|
5629 | | - active->linetime = hw->wm_linetime[pipe]; |
---|
5630 | 6319 | } else { |
---|
5631 | 6320 | int level, max_level = ilk_wm_max_level(dev_priv); |
---|
5632 | 6321 | |
---|
.. | .. |
---|
5639 | 6328 | active->wm[level].enable = true; |
---|
5640 | 6329 | } |
---|
5641 | 6330 | |
---|
5642 | | - intel_crtc->wm.active.ilk = *active; |
---|
| 6331 | + crtc->wm.active.ilk = *active; |
---|
5643 | 6332 | } |
---|
5644 | 6333 | |
---|
5645 | 6334 | #define _FW_WM(value, plane) \ |
---|
.. | .. |
---|
5650 | 6339 | static void g4x_read_wm_values(struct drm_i915_private *dev_priv, |
---|
5651 | 6340 | struct g4x_wm_values *wm) |
---|
5652 | 6341 | { |
---|
5653 | | - uint32_t tmp; |
---|
| 6342 | + u32 tmp; |
---|
5654 | 6343 | |
---|
5655 | 6344 | tmp = I915_READ(DSPFW1); |
---|
5656 | 6345 | wm->sr.plane = _FW_WM(tmp, SR); |
---|
.. | .. |
---|
5677 | 6366 | struct vlv_wm_values *wm) |
---|
5678 | 6367 | { |
---|
5679 | 6368 | enum pipe pipe; |
---|
5680 | | - uint32_t tmp; |
---|
| 6369 | + u32 tmp; |
---|
5681 | 6370 | |
---|
5682 | 6371 | for_each_pipe(dev_priv, pipe) { |
---|
5683 | 6372 | tmp = I915_READ(VLV_DDL(pipe)); |
---|
.. | .. |
---|
5749 | 6438 | #undef _FW_WM |
---|
5750 | 6439 | #undef _FW_WM_VLV |
---|
5751 | 6440 | |
---|
5752 | | -void g4x_wm_get_hw_state(struct drm_device *dev) |
---|
| 6441 | +void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) |
---|
5753 | 6442 | { |
---|
5754 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
5755 | 6443 | struct g4x_wm_values *wm = &dev_priv->wm.g4x; |
---|
5756 | 6444 | struct intel_crtc *crtc; |
---|
5757 | 6445 | |
---|
.. | .. |
---|
5759 | 6447 | |
---|
5760 | 6448 | wm->cxsr = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; |
---|
5761 | 6449 | |
---|
5762 | | - for_each_intel_crtc(dev, crtc) { |
---|
| 6450 | + for_each_intel_crtc(&dev_priv->drm, crtc) { |
---|
5763 | 6451 | struct intel_crtc_state *crtc_state = |
---|
5764 | 6452 | to_intel_crtc_state(crtc->base.state); |
---|
5765 | 6453 | struct g4x_wm_state *active = &crtc->wm.active.g4x; |
---|
.. | .. |
---|
5819 | 6507 | crtc_state->wm.g4x.optimal = *active; |
---|
5820 | 6508 | crtc_state->wm.g4x.intermediate = *active; |
---|
5821 | 6509 | |
---|
5822 | | - DRM_DEBUG_KMS("Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite=%d\n", |
---|
5823 | | - pipe_name(pipe), |
---|
5824 | | - wm->pipe[pipe].plane[PLANE_PRIMARY], |
---|
5825 | | - wm->pipe[pipe].plane[PLANE_CURSOR], |
---|
5826 | | - wm->pipe[pipe].plane[PLANE_SPRITE0]); |
---|
| 6510 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 6511 | + "Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite=%d\n", |
---|
| 6512 | + pipe_name(pipe), |
---|
| 6513 | + wm->pipe[pipe].plane[PLANE_PRIMARY], |
---|
| 6514 | + wm->pipe[pipe].plane[PLANE_CURSOR], |
---|
| 6515 | + wm->pipe[pipe].plane[PLANE_SPRITE0]); |
---|
5827 | 6516 | } |
---|
5828 | 6517 | |
---|
5829 | | - DRM_DEBUG_KMS("Initial SR watermarks: plane=%d, cursor=%d fbc=%d\n", |
---|
5830 | | - wm->sr.plane, wm->sr.cursor, wm->sr.fbc); |
---|
5831 | | - DRM_DEBUG_KMS("Initial HPLL watermarks: plane=%d, SR cursor=%d fbc=%d\n", |
---|
5832 | | - wm->hpll.plane, wm->hpll.cursor, wm->hpll.fbc); |
---|
5833 | | - DRM_DEBUG_KMS("Initial SR=%s HPLL=%s FBC=%s\n", |
---|
5834 | | - yesno(wm->cxsr), yesno(wm->hpll_en), yesno(wm->fbc_en)); |
---|
| 6518 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 6519 | + "Initial SR watermarks: plane=%d, cursor=%d fbc=%d\n", |
---|
| 6520 | + wm->sr.plane, wm->sr.cursor, wm->sr.fbc); |
---|
| 6521 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 6522 | + "Initial HPLL watermarks: plane=%d, SR cursor=%d fbc=%d\n", |
---|
| 6523 | + wm->hpll.plane, wm->hpll.cursor, wm->hpll.fbc); |
---|
| 6524 | + drm_dbg_kms(&dev_priv->drm, "Initial SR=%s HPLL=%s FBC=%s\n", |
---|
| 6525 | + yesno(wm->cxsr), yesno(wm->hpll_en), yesno(wm->fbc_en)); |
---|
5835 | 6526 | } |
---|
5836 | 6527 | |
---|
5837 | 6528 | void g4x_wm_sanitize(struct drm_i915_private *dev_priv) |
---|
.. | .. |
---|
5852 | 6543 | enum plane_id plane_id = plane->id; |
---|
5853 | 6544 | int level; |
---|
5854 | 6545 | |
---|
5855 | | - if (plane_state->base.visible) |
---|
| 6546 | + if (plane_state->uapi.visible) |
---|
5856 | 6547 | continue; |
---|
5857 | 6548 | |
---|
5858 | 6549 | for (level = 0; level < 3; level++) { |
---|
.. | .. |
---|
5890 | 6581 | mutex_unlock(&dev_priv->wm.wm_mutex); |
---|
5891 | 6582 | } |
---|
5892 | 6583 | |
---|
5893 | | -void vlv_wm_get_hw_state(struct drm_device *dev) |
---|
| 6584 | +void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) |
---|
5894 | 6585 | { |
---|
5895 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
5896 | 6586 | struct vlv_wm_values *wm = &dev_priv->wm.vlv; |
---|
5897 | 6587 | struct intel_crtc *crtc; |
---|
5898 | 6588 | u32 val; |
---|
.. | .. |
---|
5903 | 6593 | wm->level = VLV_WM_LEVEL_PM2; |
---|
5904 | 6594 | |
---|
5905 | 6595 | if (IS_CHERRYVIEW(dev_priv)) { |
---|
5906 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
| 6596 | + vlv_punit_get(dev_priv); |
---|
5907 | 6597 | |
---|
5908 | | - val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); |
---|
| 6598 | + val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM); |
---|
5909 | 6599 | if (val & DSP_MAXFIFO_PM5_ENABLE) |
---|
5910 | 6600 | wm->level = VLV_WM_LEVEL_PM5; |
---|
5911 | 6601 | |
---|
.. | .. |
---|
5924 | 6614 | |
---|
5925 | 6615 | if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) & |
---|
5926 | 6616 | FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) { |
---|
5927 | | - DRM_DEBUG_KMS("Punit not acking DDR DVFS request, " |
---|
5928 | | - "assuming DDR DVFS is disabled\n"); |
---|
| 6617 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 6618 | + "Punit not acking DDR DVFS request, " |
---|
| 6619 | + "assuming DDR DVFS is disabled\n"); |
---|
5929 | 6620 | dev_priv->wm.max_level = VLV_WM_LEVEL_PM5; |
---|
5930 | 6621 | } else { |
---|
5931 | 6622 | val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2); |
---|
.. | .. |
---|
5933 | 6624 | wm->level = VLV_WM_LEVEL_DDR_DVFS; |
---|
5934 | 6625 | } |
---|
5935 | 6626 | |
---|
5936 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
| 6627 | + vlv_punit_put(dev_priv); |
---|
5937 | 6628 | } |
---|
5938 | 6629 | |
---|
5939 | | - for_each_intel_crtc(dev, crtc) { |
---|
| 6630 | + for_each_intel_crtc(&dev_priv->drm, crtc) { |
---|
5940 | 6631 | struct intel_crtc_state *crtc_state = |
---|
5941 | 6632 | to_intel_crtc_state(crtc->base.state); |
---|
5942 | 6633 | struct vlv_wm_state *active = &crtc->wm.active.vlv; |
---|
.. | .. |
---|
5976 | 6667 | crtc_state->wm.vlv.optimal = *active; |
---|
5977 | 6668 | crtc_state->wm.vlv.intermediate = *active; |
---|
5978 | 6669 | |
---|
5979 | | - DRM_DEBUG_KMS("Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite0=%d, sprite1=%d\n", |
---|
5980 | | - pipe_name(pipe), |
---|
5981 | | - wm->pipe[pipe].plane[PLANE_PRIMARY], |
---|
5982 | | - wm->pipe[pipe].plane[PLANE_CURSOR], |
---|
5983 | | - wm->pipe[pipe].plane[PLANE_SPRITE0], |
---|
5984 | | - wm->pipe[pipe].plane[PLANE_SPRITE1]); |
---|
| 6670 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 6671 | + "Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite0=%d, sprite1=%d\n", |
---|
| 6672 | + pipe_name(pipe), |
---|
| 6673 | + wm->pipe[pipe].plane[PLANE_PRIMARY], |
---|
| 6674 | + wm->pipe[pipe].plane[PLANE_CURSOR], |
---|
| 6675 | + wm->pipe[pipe].plane[PLANE_SPRITE0], |
---|
| 6676 | + wm->pipe[pipe].plane[PLANE_SPRITE1]); |
---|
5985 | 6677 | } |
---|
5986 | 6678 | |
---|
5987 | | - DRM_DEBUG_KMS("Initial watermarks: SR plane=%d, SR cursor=%d level=%d cxsr=%d\n", |
---|
5988 | | - wm->sr.plane, wm->sr.cursor, wm->level, wm->cxsr); |
---|
| 6679 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 6680 | + "Initial watermarks: SR plane=%d, SR cursor=%d level=%d cxsr=%d\n", |
---|
| 6681 | + wm->sr.plane, wm->sr.cursor, wm->level, wm->cxsr); |
---|
5989 | 6682 | } |
---|
5990 | 6683 | |
---|
5991 | 6684 | void vlv_wm_sanitize(struct drm_i915_private *dev_priv) |
---|
.. | .. |
---|
6008 | 6701 | enum plane_id plane_id = plane->id; |
---|
6009 | 6702 | int level; |
---|
6010 | 6703 | |
---|
6011 | | - if (plane_state->base.visible) |
---|
| 6704 | + if (plane_state->uapi.visible) |
---|
6012 | 6705 | continue; |
---|
6013 | 6706 | |
---|
6014 | 6707 | for (level = 0; level < wm_state->num_levels; level++) { |
---|
.. | .. |
---|
6053 | 6746 | */ |
---|
6054 | 6747 | } |
---|
6055 | 6748 | |
---|
6056 | | -void ilk_wm_get_hw_state(struct drm_device *dev) |
---|
| 6749 | +void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv) |
---|
6057 | 6750 | { |
---|
6058 | | - struct drm_i915_private *dev_priv = to_i915(dev); |
---|
6059 | 6751 | struct ilk_wm_values *hw = &dev_priv->wm.hw; |
---|
6060 | | - struct drm_crtc *crtc; |
---|
| 6752 | + struct intel_crtc *crtc; |
---|
6061 | 6753 | |
---|
6062 | 6754 | ilk_init_lp_watermarks(dev_priv); |
---|
6063 | 6755 | |
---|
6064 | | - for_each_crtc(dev, crtc) |
---|
| 6756 | + for_each_intel_crtc(&dev_priv->drm, crtc) |
---|
6065 | 6757 | ilk_pipe_wm_get_hw_state(crtc); |
---|
6066 | 6758 | |
---|
6067 | 6759 | hw->wm_lp[0] = I915_READ(WM1_LP_ILK); |
---|
.. | .. |
---|
6130 | 6822 | { |
---|
6131 | 6823 | u32 val; |
---|
6132 | 6824 | |
---|
6133 | | - /* Display WA #0477 WaDisableIPC: skl */ |
---|
6134 | | - if (IS_SKYLAKE(dev_priv)) { |
---|
6135 | | - dev_priv->ipc_enabled = false; |
---|
| 6825 | + if (!HAS_IPC(dev_priv)) |
---|
6136 | 6826 | return; |
---|
6137 | | - } |
---|
6138 | 6827 | |
---|
6139 | 6828 | val = I915_READ(DISP_ARB_CTL2); |
---|
6140 | 6829 | |
---|
.. | .. |
---|
6146 | 6835 | I915_WRITE(DISP_ARB_CTL2, val); |
---|
6147 | 6836 | } |
---|
6148 | 6837 | |
---|
| 6838 | +static bool intel_can_enable_ipc(struct drm_i915_private *dev_priv) |
---|
| 6839 | +{ |
---|
| 6840 | + /* Display WA #0477 WaDisableIPC: skl */ |
---|
| 6841 | + if (IS_SKYLAKE(dev_priv)) |
---|
| 6842 | + return false; |
---|
| 6843 | + |
---|
| 6844 | + /* Display WA #1141: SKL:all KBL:all CFL */ |
---|
| 6845 | + if (IS_KABYLAKE(dev_priv) || |
---|
| 6846 | + IS_COFFEELAKE(dev_priv) || |
---|
| 6847 | + IS_COMETLAKE(dev_priv)) |
---|
| 6848 | + return dev_priv->dram_info.symmetric_memory; |
---|
| 6849 | + |
---|
| 6850 | + return true; |
---|
| 6851 | +} |
---|
| 6852 | + |
---|
6149 | 6853 | void intel_init_ipc(struct drm_i915_private *dev_priv) |
---|
6150 | 6854 | { |
---|
6151 | | - dev_priv->ipc_enabled = false; |
---|
6152 | 6855 | if (!HAS_IPC(dev_priv)) |
---|
6153 | 6856 | return; |
---|
6154 | 6857 | |
---|
6155 | | - dev_priv->ipc_enabled = true; |
---|
| 6858 | + dev_priv->ipc_enabled = intel_can_enable_ipc(dev_priv); |
---|
| 6859 | + |
---|
6156 | 6860 | intel_enable_ipc(dev_priv); |
---|
6157 | | -} |
---|
6158 | | - |
---|
6159 | | -/* |
---|
6160 | | - * Lock protecting IPS related data structures |
---|
6161 | | - */ |
---|
6162 | | -DEFINE_SPINLOCK(mchdev_lock); |
---|
6163 | | - |
---|
6164 | | -/* Global for IPS driver to get at the current i915 device. Protected by |
---|
6165 | | - * mchdev_lock. */ |
---|
6166 | | -static struct drm_i915_private *i915_mch_dev; |
---|
6167 | | - |
---|
6168 | | -bool ironlake_set_drps(struct drm_i915_private *dev_priv, u8 val) |
---|
6169 | | -{ |
---|
6170 | | - u16 rgvswctl; |
---|
6171 | | - |
---|
6172 | | - lockdep_assert_held(&mchdev_lock); |
---|
6173 | | - |
---|
6174 | | - rgvswctl = I915_READ16(MEMSWCTL); |
---|
6175 | | - if (rgvswctl & MEMCTL_CMD_STS) { |
---|
6176 | | - DRM_DEBUG("gpu busy, RCS change rejected\n"); |
---|
6177 | | - return false; /* still busy with another command */ |
---|
6178 | | - } |
---|
6179 | | - |
---|
6180 | | - rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | |
---|
6181 | | - (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; |
---|
6182 | | - I915_WRITE16(MEMSWCTL, rgvswctl); |
---|
6183 | | - POSTING_READ16(MEMSWCTL); |
---|
6184 | | - |
---|
6185 | | - rgvswctl |= MEMCTL_CMD_STS; |
---|
6186 | | - I915_WRITE16(MEMSWCTL, rgvswctl); |
---|
6187 | | - |
---|
6188 | | - return true; |
---|
6189 | | -} |
---|
6190 | | - |
---|
6191 | | -static void ironlake_enable_drps(struct drm_i915_private *dev_priv) |
---|
6192 | | -{ |
---|
6193 | | - u32 rgvmodectl; |
---|
6194 | | - u8 fmax, fmin, fstart, vstart; |
---|
6195 | | - |
---|
6196 | | - spin_lock_irq(&mchdev_lock); |
---|
6197 | | - |
---|
6198 | | - rgvmodectl = I915_READ(MEMMODECTL); |
---|
6199 | | - |
---|
6200 | | - /* Enable temp reporting */ |
---|
6201 | | - I915_WRITE16(PMMISC, I915_READ(PMMISC) | MCPPCE_EN); |
---|
6202 | | - I915_WRITE16(TSC1, I915_READ(TSC1) | TSE); |
---|
6203 | | - |
---|
6204 | | - /* 100ms RC evaluation intervals */ |
---|
6205 | | - I915_WRITE(RCUPEI, 100000); |
---|
6206 | | - I915_WRITE(RCDNEI, 100000); |
---|
6207 | | - |
---|
6208 | | - /* Set max/min thresholds to 90ms and 80ms respectively */ |
---|
6209 | | - I915_WRITE(RCBMAXAVG, 90000); |
---|
6210 | | - I915_WRITE(RCBMINAVG, 80000); |
---|
6211 | | - |
---|
6212 | | - I915_WRITE(MEMIHYST, 1); |
---|
6213 | | - |
---|
6214 | | - /* Set up min, max, and cur for interrupt handling */ |
---|
6215 | | - fmax = (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT; |
---|
6216 | | - fmin = (rgvmodectl & MEMMODE_FMIN_MASK); |
---|
6217 | | - fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> |
---|
6218 | | - MEMMODE_FSTART_SHIFT; |
---|
6219 | | - |
---|
6220 | | - vstart = (I915_READ(PXVFREQ(fstart)) & PXVFREQ_PX_MASK) >> |
---|
6221 | | - PXVFREQ_PX_SHIFT; |
---|
6222 | | - |
---|
6223 | | - dev_priv->ips.fmax = fmax; /* IPS callback will increase this */ |
---|
6224 | | - dev_priv->ips.fstart = fstart; |
---|
6225 | | - |
---|
6226 | | - dev_priv->ips.max_delay = fstart; |
---|
6227 | | - dev_priv->ips.min_delay = fmin; |
---|
6228 | | - dev_priv->ips.cur_delay = fstart; |
---|
6229 | | - |
---|
6230 | | - DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", |
---|
6231 | | - fmax, fmin, fstart); |
---|
6232 | | - |
---|
6233 | | - I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); |
---|
6234 | | - |
---|
6235 | | - /* |
---|
6236 | | - * Interrupts will be enabled in ironlake_irq_postinstall |
---|
6237 | | - */ |
---|
6238 | | - |
---|
6239 | | - I915_WRITE(VIDSTART, vstart); |
---|
6240 | | - POSTING_READ(VIDSTART); |
---|
6241 | | - |
---|
6242 | | - rgvmodectl |= MEMMODE_SWMODE_EN; |
---|
6243 | | - I915_WRITE(MEMMODECTL, rgvmodectl); |
---|
6244 | | - |
---|
6245 | | - if (wait_for_atomic((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 10)) |
---|
6246 | | - DRM_ERROR("stuck trying to change perf mode\n"); |
---|
6247 | | - mdelay(1); |
---|
6248 | | - |
---|
6249 | | - ironlake_set_drps(dev_priv, fstart); |
---|
6250 | | - |
---|
6251 | | - dev_priv->ips.last_count1 = I915_READ(DMIEC) + |
---|
6252 | | - I915_READ(DDREC) + I915_READ(CSIEC); |
---|
6253 | | - dev_priv->ips.last_time1 = jiffies_to_msecs(jiffies); |
---|
6254 | | - dev_priv->ips.last_count2 = I915_READ(GFXEC); |
---|
6255 | | - dev_priv->ips.last_time2 = ktime_get_raw_ns(); |
---|
6256 | | - |
---|
6257 | | - spin_unlock_irq(&mchdev_lock); |
---|
6258 | | -} |
---|
6259 | | - |
---|
6260 | | -static void ironlake_disable_drps(struct drm_i915_private *dev_priv) |
---|
6261 | | -{ |
---|
6262 | | - u16 rgvswctl; |
---|
6263 | | - |
---|
6264 | | - spin_lock_irq(&mchdev_lock); |
---|
6265 | | - |
---|
6266 | | - rgvswctl = I915_READ16(MEMSWCTL); |
---|
6267 | | - |
---|
6268 | | - /* Ack interrupts, disable EFC interrupt */ |
---|
6269 | | - I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN); |
---|
6270 | | - I915_WRITE(MEMINTRSTS, MEMINT_EVAL_CHG); |
---|
6271 | | - I915_WRITE(DEIER, I915_READ(DEIER) & ~DE_PCU_EVENT); |
---|
6272 | | - I915_WRITE(DEIIR, DE_PCU_EVENT); |
---|
6273 | | - I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); |
---|
6274 | | - |
---|
6275 | | - /* Go back to the starting frequency */ |
---|
6276 | | - ironlake_set_drps(dev_priv, dev_priv->ips.fstart); |
---|
6277 | | - mdelay(1); |
---|
6278 | | - rgvswctl |= MEMCTL_CMD_STS; |
---|
6279 | | - I915_WRITE(MEMSWCTL, rgvswctl); |
---|
6280 | | - mdelay(1); |
---|
6281 | | - |
---|
6282 | | - spin_unlock_irq(&mchdev_lock); |
---|
6283 | | -} |
---|
6284 | | - |
---|
6285 | | -/* There's a funny hw issue where the hw returns all 0 when reading from |
---|
6286 | | - * GEN6_RP_INTERRUPT_LIMITS. Hence we always need to compute the desired value |
---|
6287 | | - * ourselves, instead of doing a rmw cycle (which might result in us clearing |
---|
6288 | | - * all limits and the gpu stuck at whatever frequency it is at atm). |
---|
6289 | | - */ |
---|
6290 | | -static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val) |
---|
6291 | | -{ |
---|
6292 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
6293 | | - u32 limits; |
---|
6294 | | - |
---|
6295 | | - /* Only set the down limit when we've reached the lowest level to avoid |
---|
6296 | | - * getting more interrupts, otherwise leave this clear. This prevents a |
---|
6297 | | - * race in the hw when coming out of rc6: There's a tiny window where |
---|
6298 | | - * the hw runs at the minimal clock before selecting the desired |
---|
6299 | | - * frequency, if the down threshold expires in that window we will not |
---|
6300 | | - * receive a down interrupt. */ |
---|
6301 | | - if (INTEL_GEN(dev_priv) >= 9) { |
---|
6302 | | - limits = (rps->max_freq_softlimit) << 23; |
---|
6303 | | - if (val <= rps->min_freq_softlimit) |
---|
6304 | | - limits |= (rps->min_freq_softlimit) << 14; |
---|
6305 | | - } else { |
---|
6306 | | - limits = rps->max_freq_softlimit << 24; |
---|
6307 | | - if (val <= rps->min_freq_softlimit) |
---|
6308 | | - limits |= rps->min_freq_softlimit << 16; |
---|
6309 | | - } |
---|
6310 | | - |
---|
6311 | | - return limits; |
---|
6312 | | -} |
---|
6313 | | - |
---|
6314 | | -static void rps_set_power(struct drm_i915_private *dev_priv, int new_power) |
---|
6315 | | -{ |
---|
6316 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
6317 | | - u32 threshold_up = 0, threshold_down = 0; /* in % */ |
---|
6318 | | - u32 ei_up = 0, ei_down = 0; |
---|
6319 | | - |
---|
6320 | | - lockdep_assert_held(&rps->power.mutex); |
---|
6321 | | - |
---|
6322 | | - if (new_power == rps->power.mode) |
---|
6323 | | - return; |
---|
6324 | | - |
---|
6325 | | - /* Note the units here are not exactly 1us, but 1280ns. */ |
---|
6326 | | - switch (new_power) { |
---|
6327 | | - case LOW_POWER: |
---|
6328 | | - /* Upclock if more than 95% busy over 16ms */ |
---|
6329 | | - ei_up = 16000; |
---|
6330 | | - threshold_up = 95; |
---|
6331 | | - |
---|
6332 | | - /* Downclock if less than 85% busy over 32ms */ |
---|
6333 | | - ei_down = 32000; |
---|
6334 | | - threshold_down = 85; |
---|
6335 | | - break; |
---|
6336 | | - |
---|
6337 | | - case BETWEEN: |
---|
6338 | | - /* Upclock if more than 90% busy over 13ms */ |
---|
6339 | | - ei_up = 13000; |
---|
6340 | | - threshold_up = 90; |
---|
6341 | | - |
---|
6342 | | - /* Downclock if less than 75% busy over 32ms */ |
---|
6343 | | - ei_down = 32000; |
---|
6344 | | - threshold_down = 75; |
---|
6345 | | - break; |
---|
6346 | | - |
---|
6347 | | - case HIGH_POWER: |
---|
6348 | | - /* Upclock if more than 85% busy over 10ms */ |
---|
6349 | | - ei_up = 10000; |
---|
6350 | | - threshold_up = 85; |
---|
6351 | | - |
---|
6352 | | - /* Downclock if less than 60% busy over 32ms */ |
---|
6353 | | - ei_down = 32000; |
---|
6354 | | - threshold_down = 60; |
---|
6355 | | - break; |
---|
6356 | | - } |
---|
6357 | | - |
---|
6358 | | - /* When byt can survive without system hang with dynamic |
---|
6359 | | - * sw freq adjustments, this restriction can be lifted. |
---|
6360 | | - */ |
---|
6361 | | - if (IS_VALLEYVIEW(dev_priv)) |
---|
6362 | | - goto skip_hw_write; |
---|
6363 | | - |
---|
6364 | | - I915_WRITE(GEN6_RP_UP_EI, |
---|
6365 | | - GT_INTERVAL_FROM_US(dev_priv, ei_up)); |
---|
6366 | | - I915_WRITE(GEN6_RP_UP_THRESHOLD, |
---|
6367 | | - GT_INTERVAL_FROM_US(dev_priv, |
---|
6368 | | - ei_up * threshold_up / 100)); |
---|
6369 | | - |
---|
6370 | | - I915_WRITE(GEN6_RP_DOWN_EI, |
---|
6371 | | - GT_INTERVAL_FROM_US(dev_priv, ei_down)); |
---|
6372 | | - I915_WRITE(GEN6_RP_DOWN_THRESHOLD, |
---|
6373 | | - GT_INTERVAL_FROM_US(dev_priv, |
---|
6374 | | - ei_down * threshold_down / 100)); |
---|
6375 | | - |
---|
6376 | | - I915_WRITE(GEN6_RP_CONTROL, |
---|
6377 | | - GEN6_RP_MEDIA_TURBO | |
---|
6378 | | - GEN6_RP_MEDIA_HW_NORMAL_MODE | |
---|
6379 | | - GEN6_RP_MEDIA_IS_GFX | |
---|
6380 | | - GEN6_RP_ENABLE | |
---|
6381 | | - GEN6_RP_UP_BUSY_AVG | |
---|
6382 | | - GEN6_RP_DOWN_IDLE_AVG); |
---|
6383 | | - |
---|
6384 | | -skip_hw_write: |
---|
6385 | | - rps->power.mode = new_power; |
---|
6386 | | - rps->power.up_threshold = threshold_up; |
---|
6387 | | - rps->power.down_threshold = threshold_down; |
---|
6388 | | -} |
---|
6389 | | - |
---|
6390 | | -static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) |
---|
6391 | | -{ |
---|
6392 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
6393 | | - int new_power; |
---|
6394 | | - |
---|
6395 | | - new_power = rps->power.mode; |
---|
6396 | | - switch (rps->power.mode) { |
---|
6397 | | - case LOW_POWER: |
---|
6398 | | - if (val > rps->efficient_freq + 1 && |
---|
6399 | | - val > rps->cur_freq) |
---|
6400 | | - new_power = BETWEEN; |
---|
6401 | | - break; |
---|
6402 | | - |
---|
6403 | | - case BETWEEN: |
---|
6404 | | - if (val <= rps->efficient_freq && |
---|
6405 | | - val < rps->cur_freq) |
---|
6406 | | - new_power = LOW_POWER; |
---|
6407 | | - else if (val >= rps->rp0_freq && |
---|
6408 | | - val > rps->cur_freq) |
---|
6409 | | - new_power = HIGH_POWER; |
---|
6410 | | - break; |
---|
6411 | | - |
---|
6412 | | - case HIGH_POWER: |
---|
6413 | | - if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 && |
---|
6414 | | - val < rps->cur_freq) |
---|
6415 | | - new_power = BETWEEN; |
---|
6416 | | - break; |
---|
6417 | | - } |
---|
6418 | | - /* Max/min bins are special */ |
---|
6419 | | - if (val <= rps->min_freq_softlimit) |
---|
6420 | | - new_power = LOW_POWER; |
---|
6421 | | - if (val >= rps->max_freq_softlimit) |
---|
6422 | | - new_power = HIGH_POWER; |
---|
6423 | | - |
---|
6424 | | - mutex_lock(&rps->power.mutex); |
---|
6425 | | - if (rps->power.interactive) |
---|
6426 | | - new_power = HIGH_POWER; |
---|
6427 | | - rps_set_power(dev_priv, new_power); |
---|
6428 | | - mutex_unlock(&rps->power.mutex); |
---|
6429 | | - rps->last_adj = 0; |
---|
6430 | | -} |
---|
6431 | | - |
---|
6432 | | -void intel_rps_mark_interactive(struct drm_i915_private *i915, bool interactive) |
---|
6433 | | -{ |
---|
6434 | | - struct intel_rps *rps = &i915->gt_pm.rps; |
---|
6435 | | - |
---|
6436 | | - if (INTEL_GEN(i915) < 6) |
---|
6437 | | - return; |
---|
6438 | | - |
---|
6439 | | - mutex_lock(&rps->power.mutex); |
---|
6440 | | - if (interactive) { |
---|
6441 | | - if (!rps->power.interactive++ && READ_ONCE(i915->gt.awake)) |
---|
6442 | | - rps_set_power(i915, HIGH_POWER); |
---|
6443 | | - } else { |
---|
6444 | | - GEM_BUG_ON(!rps->power.interactive); |
---|
6445 | | - rps->power.interactive--; |
---|
6446 | | - } |
---|
6447 | | - mutex_unlock(&rps->power.mutex); |
---|
6448 | | -} |
---|
6449 | | - |
---|
6450 | | -static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) |
---|
6451 | | -{ |
---|
6452 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
6453 | | - u32 mask = 0; |
---|
6454 | | - |
---|
6455 | | - /* We use UP_EI_EXPIRED interupts for both up/down in manual mode */ |
---|
6456 | | - if (val > rps->min_freq_softlimit) |
---|
6457 | | - mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; |
---|
6458 | | - if (val < rps->max_freq_softlimit) |
---|
6459 | | - mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD; |
---|
6460 | | - |
---|
6461 | | - mask &= dev_priv->pm_rps_events; |
---|
6462 | | - |
---|
6463 | | - return gen6_sanitize_rps_pm_mask(dev_priv, ~mask); |
---|
6464 | | -} |
---|
6465 | | - |
---|
6466 | | -/* gen6_set_rps is called to update the frequency request, but should also be |
---|
6467 | | - * called when the range (min_delay and max_delay) is modified so that we can |
---|
6468 | | - * update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */ |
---|
6469 | | -static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val) |
---|
6470 | | -{ |
---|
6471 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
6472 | | - |
---|
6473 | | - /* min/max delay may still have been modified so be sure to |
---|
6474 | | - * write the limits value. |
---|
6475 | | - */ |
---|
6476 | | - if (val != rps->cur_freq) { |
---|
6477 | | - gen6_set_rps_thresholds(dev_priv, val); |
---|
6478 | | - |
---|
6479 | | - if (INTEL_GEN(dev_priv) >= 9) |
---|
6480 | | - I915_WRITE(GEN6_RPNSWREQ, |
---|
6481 | | - GEN9_FREQUENCY(val)); |
---|
6482 | | - else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) |
---|
6483 | | - I915_WRITE(GEN6_RPNSWREQ, |
---|
6484 | | - HSW_FREQUENCY(val)); |
---|
6485 | | - else |
---|
6486 | | - I915_WRITE(GEN6_RPNSWREQ, |
---|
6487 | | - GEN6_FREQUENCY(val) | |
---|
6488 | | - GEN6_OFFSET(0) | |
---|
6489 | | - GEN6_AGGRESSIVE_TURBO); |
---|
6490 | | - } |
---|
6491 | | - |
---|
6492 | | - /* Make sure we continue to get interrupts |
---|
6493 | | - * until we hit the minimum or maximum frequencies. |
---|
6494 | | - */ |
---|
6495 | | - I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, intel_rps_limits(dev_priv, val)); |
---|
6496 | | - I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); |
---|
6497 | | - |
---|
6498 | | - rps->cur_freq = val; |
---|
6499 | | - trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); |
---|
6500 | | - |
---|
6501 | | - return 0; |
---|
6502 | | -} |
---|
6503 | | - |
---|
6504 | | -static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val) |
---|
6505 | | -{ |
---|
6506 | | - int err; |
---|
6507 | | - |
---|
6508 | | - if (WARN_ONCE(IS_CHERRYVIEW(dev_priv) && (val & 1), |
---|
6509 | | - "Odd GPU freq value\n")) |
---|
6510 | | - val &= ~1; |
---|
6511 | | - |
---|
6512 | | - I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); |
---|
6513 | | - |
---|
6514 | | - if (val != dev_priv->gt_pm.rps.cur_freq) { |
---|
6515 | | - err = vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); |
---|
6516 | | - if (err) |
---|
6517 | | - return err; |
---|
6518 | | - |
---|
6519 | | - gen6_set_rps_thresholds(dev_priv, val); |
---|
6520 | | - } |
---|
6521 | | - |
---|
6522 | | - dev_priv->gt_pm.rps.cur_freq = val; |
---|
6523 | | - trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); |
---|
6524 | | - |
---|
6525 | | - return 0; |
---|
6526 | | -} |
---|
6527 | | - |
---|
6528 | | -/* vlv_set_rps_idle: Set the frequency to idle, if Gfx clocks are down |
---|
6529 | | - * |
---|
6530 | | - * * If Gfx is Idle, then |
---|
6531 | | - * 1. Forcewake Media well. |
---|
6532 | | - * 2. Request idle freq. |
---|
6533 | | - * 3. Release Forcewake of Media well. |
---|
6534 | | -*/ |
---|
6535 | | -static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) |
---|
6536 | | -{ |
---|
6537 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
6538 | | - u32 val = rps->idle_freq; |
---|
6539 | | - int err; |
---|
6540 | | - |
---|
6541 | | - if (rps->cur_freq <= val) |
---|
6542 | | - return; |
---|
6543 | | - |
---|
6544 | | - /* The punit delays the write of the frequency and voltage until it |
---|
6545 | | - * determines the GPU is awake. During normal usage we don't want to |
---|
6546 | | - * waste power changing the frequency if the GPU is sleeping (rc6). |
---|
6547 | | - * However, the GPU and driver is now idle and we do not want to delay |
---|
6548 | | - * switching to minimum voltage (reducing power whilst idle) as we do |
---|
6549 | | - * not expect to be woken in the near future and so must flush the |
---|
6550 | | - * change by waking the device. |
---|
6551 | | - * |
---|
6552 | | - * We choose to take the media powerwell (either would do to trick the |
---|
6553 | | - * punit into committing the voltage change) as that takes a lot less |
---|
6554 | | - * power than the render powerwell. |
---|
6555 | | - */ |
---|
6556 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_MEDIA); |
---|
6557 | | - err = valleyview_set_rps(dev_priv, val); |
---|
6558 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_MEDIA); |
---|
6559 | | - |
---|
6560 | | - if (err) |
---|
6561 | | - DRM_ERROR("Failed to set RPS for idle\n"); |
---|
6562 | | -} |
---|
6563 | | - |
---|
6564 | | -void gen6_rps_busy(struct drm_i915_private *dev_priv) |
---|
6565 | | -{ |
---|
6566 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
6567 | | - |
---|
6568 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
6569 | | - if (rps->enabled) { |
---|
6570 | | - u8 freq; |
---|
6571 | | - |
---|
6572 | | - if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED) |
---|
6573 | | - gen6_rps_reset_ei(dev_priv); |
---|
6574 | | - I915_WRITE(GEN6_PMINTRMSK, |
---|
6575 | | - gen6_rps_pm_mask(dev_priv, rps->cur_freq)); |
---|
6576 | | - |
---|
6577 | | - gen6_enable_rps_interrupts(dev_priv); |
---|
6578 | | - |
---|
6579 | | - /* Use the user's desired frequency as a guide, but for better |
---|
6580 | | - * performance, jump directly to RPe as our starting frequency. |
---|
6581 | | - */ |
---|
6582 | | - freq = max(rps->cur_freq, |
---|
6583 | | - rps->efficient_freq); |
---|
6584 | | - |
---|
6585 | | - if (intel_set_rps(dev_priv, |
---|
6586 | | - clamp(freq, |
---|
6587 | | - rps->min_freq_softlimit, |
---|
6588 | | - rps->max_freq_softlimit))) |
---|
6589 | | - DRM_DEBUG_DRIVER("Failed to set idle frequency\n"); |
---|
6590 | | - } |
---|
6591 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
6592 | | -} |
---|
6593 | | - |
---|
6594 | | -void gen6_rps_idle(struct drm_i915_private *dev_priv) |
---|
6595 | | -{ |
---|
6596 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
6597 | | - |
---|
6598 | | - /* Flush our bottom-half so that it does not race with us |
---|
6599 | | - * setting the idle frequency and so that it is bounded by |
---|
6600 | | - * our rpm wakeref. And then disable the interrupts to stop any |
---|
6601 | | - * futher RPS reclocking whilst we are asleep. |
---|
6602 | | - */ |
---|
6603 | | - gen6_disable_rps_interrupts(dev_priv); |
---|
6604 | | - |
---|
6605 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
6606 | | - if (rps->enabled) { |
---|
6607 | | - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) |
---|
6608 | | - vlv_set_rps_idle(dev_priv); |
---|
6609 | | - else |
---|
6610 | | - gen6_set_rps(dev_priv, rps->idle_freq); |
---|
6611 | | - rps->last_adj = 0; |
---|
6612 | | - I915_WRITE(GEN6_PMINTRMSK, |
---|
6613 | | - gen6_sanitize_rps_pm_mask(dev_priv, ~0)); |
---|
6614 | | - } |
---|
6615 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
6616 | | -} |
---|
6617 | | - |
---|
6618 | | -void gen6_rps_boost(struct i915_request *rq, |
---|
6619 | | - struct intel_rps_client *rps_client) |
---|
6620 | | -{ |
---|
6621 | | - struct intel_rps *rps = &rq->i915->gt_pm.rps; |
---|
6622 | | - unsigned long flags; |
---|
6623 | | - bool boost; |
---|
6624 | | - |
---|
6625 | | - /* This is intentionally racy! We peek at the state here, then |
---|
6626 | | - * validate inside the RPS worker. |
---|
6627 | | - */ |
---|
6628 | | - if (!rps->enabled) |
---|
6629 | | - return; |
---|
6630 | | - |
---|
6631 | | - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags)) |
---|
6632 | | - return; |
---|
6633 | | - |
---|
6634 | | - /* Serializes with i915_request_retire() */ |
---|
6635 | | - boost = false; |
---|
6636 | | - spin_lock_irqsave(&rq->lock, flags); |
---|
6637 | | - if (!rq->waitboost && !dma_fence_is_signaled_locked(&rq->fence)) { |
---|
6638 | | - boost = !atomic_fetch_inc(&rps->num_waiters); |
---|
6639 | | - rq->waitboost = true; |
---|
6640 | | - } |
---|
6641 | | - spin_unlock_irqrestore(&rq->lock, flags); |
---|
6642 | | - if (!boost) |
---|
6643 | | - return; |
---|
6644 | | - |
---|
6645 | | - if (READ_ONCE(rps->cur_freq) < rps->boost_freq) |
---|
6646 | | - schedule_work(&rps->work); |
---|
6647 | | - |
---|
6648 | | - atomic_inc(rps_client ? &rps_client->boosts : &rps->boosts); |
---|
6649 | | -} |
---|
6650 | | - |
---|
6651 | | -int intel_set_rps(struct drm_i915_private *dev_priv, u8 val) |
---|
6652 | | -{ |
---|
6653 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
6654 | | - int err; |
---|
6655 | | - |
---|
6656 | | - lockdep_assert_held(&dev_priv->pcu_lock); |
---|
6657 | | - GEM_BUG_ON(val > rps->max_freq); |
---|
6658 | | - GEM_BUG_ON(val < rps->min_freq); |
---|
6659 | | - |
---|
6660 | | - if (!rps->enabled) { |
---|
6661 | | - rps->cur_freq = val; |
---|
6662 | | - return 0; |
---|
6663 | | - } |
---|
6664 | | - |
---|
6665 | | - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) |
---|
6666 | | - err = valleyview_set_rps(dev_priv, val); |
---|
6667 | | - else |
---|
6668 | | - err = gen6_set_rps(dev_priv, val); |
---|
6669 | | - |
---|
6670 | | - return err; |
---|
6671 | | -} |
---|
6672 | | - |
---|
6673 | | -static void gen9_disable_rc6(struct drm_i915_private *dev_priv) |
---|
6674 | | -{ |
---|
6675 | | - I915_WRITE(GEN6_RC_CONTROL, 0); |
---|
6676 | | - I915_WRITE(GEN9_PG_ENABLE, 0); |
---|
6677 | | -} |
---|
6678 | | - |
---|
6679 | | -static void gen9_disable_rps(struct drm_i915_private *dev_priv) |
---|
6680 | | -{ |
---|
6681 | | - I915_WRITE(GEN6_RP_CONTROL, 0); |
---|
6682 | | -} |
---|
6683 | | - |
---|
6684 | | -static void gen6_disable_rc6(struct drm_i915_private *dev_priv) |
---|
6685 | | -{ |
---|
6686 | | - I915_WRITE(GEN6_RC_CONTROL, 0); |
---|
6687 | | -} |
---|
6688 | | - |
---|
6689 | | -static void gen6_disable_rps(struct drm_i915_private *dev_priv) |
---|
6690 | | -{ |
---|
6691 | | - I915_WRITE(GEN6_RPNSWREQ, 1 << 31); |
---|
6692 | | - I915_WRITE(GEN6_RP_CONTROL, 0); |
---|
6693 | | -} |
---|
6694 | | - |
---|
6695 | | -static void cherryview_disable_rc6(struct drm_i915_private *dev_priv) |
---|
6696 | | -{ |
---|
6697 | | - I915_WRITE(GEN6_RC_CONTROL, 0); |
---|
6698 | | -} |
---|
6699 | | - |
---|
6700 | | -static void cherryview_disable_rps(struct drm_i915_private *dev_priv) |
---|
6701 | | -{ |
---|
6702 | | - I915_WRITE(GEN6_RP_CONTROL, 0); |
---|
6703 | | -} |
---|
6704 | | - |
---|
6705 | | -static void valleyview_disable_rc6(struct drm_i915_private *dev_priv) |
---|
6706 | | -{ |
---|
6707 | | - /* We're doing forcewake before Disabling RC6, |
---|
6708 | | - * This what the BIOS expects when going into suspend */ |
---|
6709 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
---|
6710 | | - |
---|
6711 | | - I915_WRITE(GEN6_RC_CONTROL, 0); |
---|
6712 | | - |
---|
6713 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
---|
6714 | | -} |
---|
6715 | | - |
---|
6716 | | -static void valleyview_disable_rps(struct drm_i915_private *dev_priv) |
---|
6717 | | -{ |
---|
6718 | | - I915_WRITE(GEN6_RP_CONTROL, 0); |
---|
6719 | | -} |
---|
6720 | | - |
---|
6721 | | -static bool bxt_check_bios_rc6_setup(struct drm_i915_private *dev_priv) |
---|
6722 | | -{ |
---|
6723 | | - bool enable_rc6 = true; |
---|
6724 | | - unsigned long rc6_ctx_base; |
---|
6725 | | - u32 rc_ctl; |
---|
6726 | | - int rc_sw_target; |
---|
6727 | | - |
---|
6728 | | - rc_ctl = I915_READ(GEN6_RC_CONTROL); |
---|
6729 | | - rc_sw_target = (I915_READ(GEN6_RC_STATE) & RC_SW_TARGET_STATE_MASK) >> |
---|
6730 | | - RC_SW_TARGET_STATE_SHIFT; |
---|
6731 | | - DRM_DEBUG_DRIVER("BIOS enabled RC states: " |
---|
6732 | | - "HW_CTRL %s HW_RC6 %s SW_TARGET_STATE %x\n", |
---|
6733 | | - onoff(rc_ctl & GEN6_RC_CTL_HW_ENABLE), |
---|
6734 | | - onoff(rc_ctl & GEN6_RC_CTL_RC6_ENABLE), |
---|
6735 | | - rc_sw_target); |
---|
6736 | | - |
---|
6737 | | - if (!(I915_READ(RC6_LOCATION) & RC6_CTX_IN_DRAM)) { |
---|
6738 | | - DRM_DEBUG_DRIVER("RC6 Base location not set properly.\n"); |
---|
6739 | | - enable_rc6 = false; |
---|
6740 | | - } |
---|
6741 | | - |
---|
6742 | | - /* |
---|
6743 | | - * The exact context size is not known for BXT, so assume a page size |
---|
6744 | | - * for this check. |
---|
6745 | | - */ |
---|
6746 | | - rc6_ctx_base = I915_READ(RC6_CTX_BASE) & RC6_CTX_BASE_MASK; |
---|
6747 | | - if (!((rc6_ctx_base >= dev_priv->dsm_reserved.start) && |
---|
6748 | | - (rc6_ctx_base + PAGE_SIZE < dev_priv->dsm_reserved.end))) { |
---|
6749 | | - DRM_DEBUG_DRIVER("RC6 Base address not as expected.\n"); |
---|
6750 | | - enable_rc6 = false; |
---|
6751 | | - } |
---|
6752 | | - |
---|
6753 | | - if (!(((I915_READ(PWRCTX_MAXCNT_RCSUNIT) & IDLE_TIME_MASK) > 1) && |
---|
6754 | | - ((I915_READ(PWRCTX_MAXCNT_VCSUNIT0) & IDLE_TIME_MASK) > 1) && |
---|
6755 | | - ((I915_READ(PWRCTX_MAXCNT_BCSUNIT) & IDLE_TIME_MASK) > 1) && |
---|
6756 | | - ((I915_READ(PWRCTX_MAXCNT_VECSUNIT) & IDLE_TIME_MASK) > 1))) { |
---|
6757 | | - DRM_DEBUG_DRIVER("Engine Idle wait time not set properly.\n"); |
---|
6758 | | - enable_rc6 = false; |
---|
6759 | | - } |
---|
6760 | | - |
---|
6761 | | - if (!I915_READ(GEN8_PUSHBUS_CONTROL) || |
---|
6762 | | - !I915_READ(GEN8_PUSHBUS_ENABLE) || |
---|
6763 | | - !I915_READ(GEN8_PUSHBUS_SHIFT)) { |
---|
6764 | | - DRM_DEBUG_DRIVER("Pushbus not setup properly.\n"); |
---|
6765 | | - enable_rc6 = false; |
---|
6766 | | - } |
---|
6767 | | - |
---|
6768 | | - if (!I915_READ(GEN6_GFXPAUSE)) { |
---|
6769 | | - DRM_DEBUG_DRIVER("GFX pause not setup properly.\n"); |
---|
6770 | | - enable_rc6 = false; |
---|
6771 | | - } |
---|
6772 | | - |
---|
6773 | | - if (!I915_READ(GEN8_MISC_CTRL0)) { |
---|
6774 | | - DRM_DEBUG_DRIVER("GPM control not setup properly.\n"); |
---|
6775 | | - enable_rc6 = false; |
---|
6776 | | - } |
---|
6777 | | - |
---|
6778 | | - return enable_rc6; |
---|
6779 | | -} |
---|
6780 | | - |
---|
6781 | | -static bool sanitize_rc6(struct drm_i915_private *i915) |
---|
6782 | | -{ |
---|
6783 | | - struct intel_device_info *info = mkwrite_device_info(i915); |
---|
6784 | | - |
---|
6785 | | - /* Powersaving is controlled by the host when inside a VM */ |
---|
6786 | | - if (intel_vgpu_active(i915)) |
---|
6787 | | - info->has_rc6 = 0; |
---|
6788 | | - |
---|
6789 | | - if (info->has_rc6 && |
---|
6790 | | - IS_GEN9_LP(i915) && !bxt_check_bios_rc6_setup(i915)) { |
---|
6791 | | - DRM_INFO("RC6 disabled by BIOS\n"); |
---|
6792 | | - info->has_rc6 = 0; |
---|
6793 | | - } |
---|
6794 | | - |
---|
6795 | | - /* |
---|
6796 | | - * We assume that we do not have any deep rc6 levels if we don't have |
---|
6797 | | - * have the previous rc6 level supported, i.e. we use HAS_RC6() |
---|
6798 | | - * as the initial coarse check for rc6 in general, moving on to |
---|
6799 | | - * progressively finer/deeper levels. |
---|
6800 | | - */ |
---|
6801 | | - if (!info->has_rc6 && info->has_rc6p) |
---|
6802 | | - info->has_rc6p = 0; |
---|
6803 | | - |
---|
6804 | | - return info->has_rc6; |
---|
6805 | | -} |
---|
6806 | | - |
---|
6807 | | -static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv) |
---|
6808 | | -{ |
---|
6809 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
6810 | | - |
---|
6811 | | - /* All of these values are in units of 50MHz */ |
---|
6812 | | - |
---|
6813 | | - /* static values from HW: RP0 > RP1 > RPn (min_freq) */ |
---|
6814 | | - if (IS_GEN9_LP(dev_priv)) { |
---|
6815 | | - u32 rp_state_cap = I915_READ(BXT_RP_STATE_CAP); |
---|
6816 | | - rps->rp0_freq = (rp_state_cap >> 16) & 0xff; |
---|
6817 | | - rps->rp1_freq = (rp_state_cap >> 8) & 0xff; |
---|
6818 | | - rps->min_freq = (rp_state_cap >> 0) & 0xff; |
---|
6819 | | - } else { |
---|
6820 | | - u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); |
---|
6821 | | - rps->rp0_freq = (rp_state_cap >> 0) & 0xff; |
---|
6822 | | - rps->rp1_freq = (rp_state_cap >> 8) & 0xff; |
---|
6823 | | - rps->min_freq = (rp_state_cap >> 16) & 0xff; |
---|
6824 | | - } |
---|
6825 | | - /* hw_max = RP0 until we check for overclocking */ |
---|
6826 | | - rps->max_freq = rps->rp0_freq; |
---|
6827 | | - |
---|
6828 | | - rps->efficient_freq = rps->rp1_freq; |
---|
6829 | | - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) || |
---|
6830 | | - IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) { |
---|
6831 | | - u32 ddcc_status = 0; |
---|
6832 | | - |
---|
6833 | | - if (sandybridge_pcode_read(dev_priv, |
---|
6834 | | - HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL, |
---|
6835 | | - &ddcc_status) == 0) |
---|
6836 | | - rps->efficient_freq = |
---|
6837 | | - clamp_t(u8, |
---|
6838 | | - ((ddcc_status >> 8) & 0xff), |
---|
6839 | | - rps->min_freq, |
---|
6840 | | - rps->max_freq); |
---|
6841 | | - } |
---|
6842 | | - |
---|
6843 | | - if (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) { |
---|
6844 | | - /* Store the frequency values in 16.66 MHZ units, which is |
---|
6845 | | - * the natural hardware unit for SKL |
---|
6846 | | - */ |
---|
6847 | | - rps->rp0_freq *= GEN9_FREQ_SCALER; |
---|
6848 | | - rps->rp1_freq *= GEN9_FREQ_SCALER; |
---|
6849 | | - rps->min_freq *= GEN9_FREQ_SCALER; |
---|
6850 | | - rps->max_freq *= GEN9_FREQ_SCALER; |
---|
6851 | | - rps->efficient_freq *= GEN9_FREQ_SCALER; |
---|
6852 | | - } |
---|
6853 | | -} |
---|
6854 | | - |
---|
6855 | | -static void reset_rps(struct drm_i915_private *dev_priv, |
---|
6856 | | - int (*set)(struct drm_i915_private *, u8)) |
---|
6857 | | -{ |
---|
6858 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
6859 | | - u8 freq = rps->cur_freq; |
---|
6860 | | - |
---|
6861 | | - /* force a reset */ |
---|
6862 | | - rps->power.mode = -1; |
---|
6863 | | - rps->cur_freq = -1; |
---|
6864 | | - |
---|
6865 | | - if (set(dev_priv, freq)) |
---|
6866 | | - DRM_ERROR("Failed to reset RPS to initial values\n"); |
---|
6867 | | -} |
---|
6868 | | - |
---|
6869 | | -/* See the Gen9_GT_PM_Programming_Guide doc for the below */ |
---|
6870 | | -static void gen9_enable_rps(struct drm_i915_private *dev_priv) |
---|
6871 | | -{ |
---|
6872 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
---|
6873 | | - |
---|
6874 | | - /* Program defaults and thresholds for RPS */ |
---|
6875 | | - if (IS_GEN9(dev_priv)) |
---|
6876 | | - I915_WRITE(GEN6_RC_VIDEO_FREQ, |
---|
6877 | | - GEN9_FREQUENCY(dev_priv->gt_pm.rps.rp1_freq)); |
---|
6878 | | - |
---|
6879 | | - /* 1 second timeout*/ |
---|
6880 | | - I915_WRITE(GEN6_RP_DOWN_TIMEOUT, |
---|
6881 | | - GT_INTERVAL_FROM_US(dev_priv, 1000000)); |
---|
6882 | | - |
---|
6883 | | - I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 0xa); |
---|
6884 | | - |
---|
6885 | | - /* Leaning on the below call to gen6_set_rps to program/setup the |
---|
6886 | | - * Up/Down EI & threshold registers, as well as the RP_CONTROL, |
---|
6887 | | - * RP_INTERRUPT_LIMITS & RPNSWREQ registers */ |
---|
6888 | | - reset_rps(dev_priv, gen6_set_rps); |
---|
6889 | | - |
---|
6890 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
---|
6891 | | -} |
---|
6892 | | - |
---|
6893 | | -static void gen9_enable_rc6(struct drm_i915_private *dev_priv) |
---|
6894 | | -{ |
---|
6895 | | - struct intel_engine_cs *engine; |
---|
6896 | | - enum intel_engine_id id; |
---|
6897 | | - u32 rc6_mode; |
---|
6898 | | - |
---|
6899 | | - /* 1a: Software RC state - RC0 */ |
---|
6900 | | - I915_WRITE(GEN6_RC_STATE, 0); |
---|
6901 | | - |
---|
6902 | | - /* 1b: Get forcewake during program sequence. Although the driver |
---|
6903 | | - * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ |
---|
6904 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
---|
6905 | | - |
---|
6906 | | - /* 2a: Disable RC states. */ |
---|
6907 | | - I915_WRITE(GEN6_RC_CONTROL, 0); |
---|
6908 | | - |
---|
6909 | | - /* 2b: Program RC6 thresholds.*/ |
---|
6910 | | - if (INTEL_GEN(dev_priv) >= 10) { |
---|
6911 | | - I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16 | 85); |
---|
6912 | | - I915_WRITE(GEN10_MEDIA_WAKE_RATE_LIMIT, 150); |
---|
6913 | | - } else if (IS_SKYLAKE(dev_priv)) { |
---|
6914 | | - /* |
---|
6915 | | - * WaRsDoubleRc6WrlWithCoarsePowerGating:skl Doubling WRL only |
---|
6916 | | - * when CPG is enabled |
---|
6917 | | - */ |
---|
6918 | | - I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16); |
---|
6919 | | - } else { |
---|
6920 | | - I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16); |
---|
6921 | | - } |
---|
6922 | | - |
---|
6923 | | - I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ |
---|
6924 | | - I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ |
---|
6925 | | - for_each_engine(engine, dev_priv, id) |
---|
6926 | | - I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); |
---|
6927 | | - |
---|
6928 | | - if (HAS_GUC(dev_priv)) |
---|
6929 | | - I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA); |
---|
6930 | | - |
---|
6931 | | - I915_WRITE(GEN6_RC_SLEEP, 0); |
---|
6932 | | - |
---|
6933 | | - /* |
---|
6934 | | - * 2c: Program Coarse Power Gating Policies. |
---|
6935 | | - * |
---|
6936 | | - * Bspec's guidance is to use 25us (really 25 * 1280ns) here. What we |
---|
6937 | | - * use instead is a more conservative estimate for the maximum time |
---|
6938 | | - * it takes us to service a CS interrupt and submit a new ELSP - that |
---|
6939 | | - * is the time which the GPU is idle waiting for the CPU to select the |
---|
6940 | | - * next request to execute. If the idle hysteresis is less than that |
---|
6941 | | - * interrupt service latency, the hardware will automatically gate |
---|
6942 | | - * the power well and we will then incur the wake up cost on top of |
---|
6943 | | - * the service latency. A similar guide from intel_pstate is that we |
---|
6944 | | - * do not want the enable hysteresis to less than the wakeup latency. |
---|
6945 | | - * |
---|
6946 | | - * igt/gem_exec_nop/sequential provides a rough estimate for the |
---|
6947 | | - * service latency, and puts it around 10us for Broadwell (and other |
---|
6948 | | - * big core) and around 40us for Broxton (and other low power cores). |
---|
6949 | | - * [Note that for legacy ringbuffer submission, this is less than 1us!] |
---|
6950 | | - * However, the wakeup latency on Broxton is closer to 100us. To be |
---|
6951 | | - * conservative, we have to factor in a context switch on top (due |
---|
6952 | | - * to ksoftirqd). |
---|
6953 | | - */ |
---|
6954 | | - I915_WRITE(GEN9_MEDIA_PG_IDLE_HYSTERESIS, 250); |
---|
6955 | | - I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 250); |
---|
6956 | | - |
---|
6957 | | - /* 3a: Enable RC6 */ |
---|
6958 | | - I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */ |
---|
6959 | | - |
---|
6960 | | - /* WaRsUseTimeoutMode:cnl (pre-prod) */ |
---|
6961 | | - if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_C0)) |
---|
6962 | | - rc6_mode = GEN7_RC_CTL_TO_MODE; |
---|
6963 | | - else |
---|
6964 | | - rc6_mode = GEN6_RC_CTL_EI_MODE(1); |
---|
6965 | | - |
---|
6966 | | - I915_WRITE(GEN6_RC_CONTROL, |
---|
6967 | | - GEN6_RC_CTL_HW_ENABLE | |
---|
6968 | | - GEN6_RC_CTL_RC6_ENABLE | |
---|
6969 | | - rc6_mode); |
---|
6970 | | - |
---|
6971 | | - /* |
---|
6972 | | - * 3b: Enable Coarse Power Gating only when RC6 is enabled. |
---|
6973 | | - * WaRsDisableCoarsePowerGating:skl,cnl - Render/Media PG need to be disabled with RC6. |
---|
6974 | | - */ |
---|
6975 | | - if (NEEDS_WaRsDisableCoarsePowerGating(dev_priv)) |
---|
6976 | | - I915_WRITE(GEN9_PG_ENABLE, 0); |
---|
6977 | | - else |
---|
6978 | | - I915_WRITE(GEN9_PG_ENABLE, |
---|
6979 | | - GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE); |
---|
6980 | | - |
---|
6981 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
---|
6982 | | -} |
---|
6983 | | - |
---|
6984 | | -static void gen8_enable_rc6(struct drm_i915_private *dev_priv) |
---|
6985 | | -{ |
---|
6986 | | - struct intel_engine_cs *engine; |
---|
6987 | | - enum intel_engine_id id; |
---|
6988 | | - |
---|
6989 | | - /* 1a: Software RC state - RC0 */ |
---|
6990 | | - I915_WRITE(GEN6_RC_STATE, 0); |
---|
6991 | | - |
---|
6992 | | - /* 1b: Get forcewake during program sequence. Although the driver |
---|
6993 | | - * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ |
---|
6994 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
---|
6995 | | - |
---|
6996 | | - /* 2a: Disable RC states. */ |
---|
6997 | | - I915_WRITE(GEN6_RC_CONTROL, 0); |
---|
6998 | | - |
---|
6999 | | - /* 2b: Program RC6 thresholds.*/ |
---|
7000 | | - I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); |
---|
7001 | | - I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ |
---|
7002 | | - I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ |
---|
7003 | | - for_each_engine(engine, dev_priv, id) |
---|
7004 | | - I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); |
---|
7005 | | - I915_WRITE(GEN6_RC_SLEEP, 0); |
---|
7006 | | - I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */ |
---|
7007 | | - |
---|
7008 | | - /* 3: Enable RC6 */ |
---|
7009 | | - |
---|
7010 | | - I915_WRITE(GEN6_RC_CONTROL, |
---|
7011 | | - GEN6_RC_CTL_HW_ENABLE | |
---|
7012 | | - GEN7_RC_CTL_TO_MODE | |
---|
7013 | | - GEN6_RC_CTL_RC6_ENABLE); |
---|
7014 | | - |
---|
7015 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
---|
7016 | | -} |
---|
7017 | | - |
---|
7018 | | -static void gen8_enable_rps(struct drm_i915_private *dev_priv) |
---|
7019 | | -{ |
---|
7020 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
7021 | | - |
---|
7022 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
---|
7023 | | - |
---|
7024 | | - /* 1 Program defaults and thresholds for RPS*/ |
---|
7025 | | - I915_WRITE(GEN6_RPNSWREQ, |
---|
7026 | | - HSW_FREQUENCY(rps->rp1_freq)); |
---|
7027 | | - I915_WRITE(GEN6_RC_VIDEO_FREQ, |
---|
7028 | | - HSW_FREQUENCY(rps->rp1_freq)); |
---|
7029 | | - /* NB: Docs say 1s, and 1000000 - which aren't equivalent */ |
---|
7030 | | - I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */ |
---|
7031 | | - |
---|
7032 | | - /* Docs recommend 900MHz, and 300 MHz respectively */ |
---|
7033 | | - I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, |
---|
7034 | | - rps->max_freq_softlimit << 24 | |
---|
7035 | | - rps->min_freq_softlimit << 16); |
---|
7036 | | - |
---|
7037 | | - I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */ |
---|
7038 | | - I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/ |
---|
7039 | | - I915_WRITE(GEN6_RP_UP_EI, 66000); /* 84.48ms, XXX: random? */ |
---|
7040 | | - I915_WRITE(GEN6_RP_DOWN_EI, 350000); /* 448ms, XXX: random? */ |
---|
7041 | | - |
---|
7042 | | - I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
---|
7043 | | - |
---|
7044 | | - /* 2: Enable RPS */ |
---|
7045 | | - I915_WRITE(GEN6_RP_CONTROL, |
---|
7046 | | - GEN6_RP_MEDIA_TURBO | |
---|
7047 | | - GEN6_RP_MEDIA_HW_NORMAL_MODE | |
---|
7048 | | - GEN6_RP_MEDIA_IS_GFX | |
---|
7049 | | - GEN6_RP_ENABLE | |
---|
7050 | | - GEN6_RP_UP_BUSY_AVG | |
---|
7051 | | - GEN6_RP_DOWN_IDLE_AVG); |
---|
7052 | | - |
---|
7053 | | - reset_rps(dev_priv, gen6_set_rps); |
---|
7054 | | - |
---|
7055 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
---|
7056 | | -} |
---|
7057 | | - |
---|
7058 | | -static void gen6_enable_rc6(struct drm_i915_private *dev_priv) |
---|
7059 | | -{ |
---|
7060 | | - struct intel_engine_cs *engine; |
---|
7061 | | - enum intel_engine_id id; |
---|
7062 | | - u32 rc6vids, rc6_mask; |
---|
7063 | | - u32 gtfifodbg; |
---|
7064 | | - int ret; |
---|
7065 | | - |
---|
7066 | | - I915_WRITE(GEN6_RC_STATE, 0); |
---|
7067 | | - |
---|
7068 | | - /* Clear the DBG now so we don't confuse earlier errors */ |
---|
7069 | | - gtfifodbg = I915_READ(GTFIFODBG); |
---|
7070 | | - if (gtfifodbg) { |
---|
7071 | | - DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg); |
---|
7072 | | - I915_WRITE(GTFIFODBG, gtfifodbg); |
---|
7073 | | - } |
---|
7074 | | - |
---|
7075 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
---|
7076 | | - |
---|
7077 | | - /* disable the counters and set deterministic thresholds */ |
---|
7078 | | - I915_WRITE(GEN6_RC_CONTROL, 0); |
---|
7079 | | - |
---|
7080 | | - I915_WRITE(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16); |
---|
7081 | | - I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30); |
---|
7082 | | - I915_WRITE(GEN6_RC6pp_WAKE_RATE_LIMIT, 30); |
---|
7083 | | - I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); |
---|
7084 | | - I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); |
---|
7085 | | - |
---|
7086 | | - for_each_engine(engine, dev_priv, id) |
---|
7087 | | - I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); |
---|
7088 | | - |
---|
7089 | | - I915_WRITE(GEN6_RC_SLEEP, 0); |
---|
7090 | | - I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); |
---|
7091 | | - if (IS_IVYBRIDGE(dev_priv)) |
---|
7092 | | - I915_WRITE(GEN6_RC6_THRESHOLD, 125000); |
---|
7093 | | - else |
---|
7094 | | - I915_WRITE(GEN6_RC6_THRESHOLD, 50000); |
---|
7095 | | - I915_WRITE(GEN6_RC6p_THRESHOLD, 150000); |
---|
7096 | | - I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ |
---|
7097 | | - |
---|
7098 | | - /* We don't use those on Haswell */ |
---|
7099 | | - rc6_mask = GEN6_RC_CTL_RC6_ENABLE; |
---|
7100 | | - if (HAS_RC6p(dev_priv)) |
---|
7101 | | - rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE; |
---|
7102 | | - if (HAS_RC6pp(dev_priv)) |
---|
7103 | | - rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE; |
---|
7104 | | - I915_WRITE(GEN6_RC_CONTROL, |
---|
7105 | | - rc6_mask | |
---|
7106 | | - GEN6_RC_CTL_EI_MODE(1) | |
---|
7107 | | - GEN6_RC_CTL_HW_ENABLE); |
---|
7108 | | - |
---|
7109 | | - rc6vids = 0; |
---|
7110 | | - ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids); |
---|
7111 | | - if (IS_GEN6(dev_priv) && ret) { |
---|
7112 | | - DRM_DEBUG_DRIVER("Couldn't check for BIOS workaround\n"); |
---|
7113 | | - } else if (IS_GEN6(dev_priv) && (GEN6_DECODE_RC6_VID(rc6vids & 0xff) < 450)) { |
---|
7114 | | - DRM_DEBUG_DRIVER("You should update your BIOS. Correcting minimum rc6 voltage (%dmV->%dmV)\n", |
---|
7115 | | - GEN6_DECODE_RC6_VID(rc6vids & 0xff), 450); |
---|
7116 | | - rc6vids &= 0xffff00; |
---|
7117 | | - rc6vids |= GEN6_ENCODE_RC6_VID(450); |
---|
7118 | | - ret = sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_RC6VIDS, rc6vids); |
---|
7119 | | - if (ret) |
---|
7120 | | - DRM_ERROR("Couldn't fix incorrect rc6 voltage\n"); |
---|
7121 | | - } |
---|
7122 | | - |
---|
7123 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
---|
7124 | | -} |
---|
7125 | | - |
---|
7126 | | -static void gen6_enable_rps(struct drm_i915_private *dev_priv) |
---|
7127 | | -{ |
---|
7128 | | - /* Here begins a magic sequence of register writes to enable |
---|
7129 | | - * auto-downclocking. |
---|
7130 | | - * |
---|
7131 | | - * Perhaps there might be some value in exposing these to |
---|
7132 | | - * userspace... |
---|
7133 | | - */ |
---|
7134 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
---|
7135 | | - |
---|
7136 | | - /* Power down if completely idle for over 50ms */ |
---|
7137 | | - I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 50000); |
---|
7138 | | - I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
---|
7139 | | - |
---|
7140 | | - reset_rps(dev_priv, gen6_set_rps); |
---|
7141 | | - |
---|
7142 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
---|
7143 | | -} |
---|
7144 | | - |
---|
7145 | | -static void gen6_update_ring_freq(struct drm_i915_private *dev_priv) |
---|
7146 | | -{ |
---|
7147 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
7148 | | - const int min_freq = 15; |
---|
7149 | | - const int scaling_factor = 180; |
---|
7150 | | - unsigned int gpu_freq; |
---|
7151 | | - unsigned int max_ia_freq, min_ring_freq; |
---|
7152 | | - unsigned int max_gpu_freq, min_gpu_freq; |
---|
7153 | | - struct cpufreq_policy *policy; |
---|
7154 | | - |
---|
7155 | | - WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); |
---|
7156 | | - |
---|
7157 | | - if (rps->max_freq <= rps->min_freq) |
---|
7158 | | - return; |
---|
7159 | | - |
---|
7160 | | - policy = cpufreq_cpu_get(0); |
---|
7161 | | - if (policy) { |
---|
7162 | | - max_ia_freq = policy->cpuinfo.max_freq; |
---|
7163 | | - cpufreq_cpu_put(policy); |
---|
7164 | | - } else { |
---|
7165 | | - /* |
---|
7166 | | - * Default to measured freq if none found, PCU will ensure we |
---|
7167 | | - * don't go over |
---|
7168 | | - */ |
---|
7169 | | - max_ia_freq = tsc_khz; |
---|
7170 | | - } |
---|
7171 | | - |
---|
7172 | | - /* Convert from kHz to MHz */ |
---|
7173 | | - max_ia_freq /= 1000; |
---|
7174 | | - |
---|
7175 | | - min_ring_freq = I915_READ(DCLK) & 0xf; |
---|
7176 | | - /* convert DDR frequency from units of 266.6MHz to bandwidth */ |
---|
7177 | | - min_ring_freq = mult_frac(min_ring_freq, 8, 3); |
---|
7178 | | - |
---|
7179 | | - min_gpu_freq = rps->min_freq; |
---|
7180 | | - max_gpu_freq = rps->max_freq; |
---|
7181 | | - if (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) { |
---|
7182 | | - /* Convert GT frequency to 50 HZ units */ |
---|
7183 | | - min_gpu_freq /= GEN9_FREQ_SCALER; |
---|
7184 | | - max_gpu_freq /= GEN9_FREQ_SCALER; |
---|
7185 | | - } |
---|
7186 | | - |
---|
7187 | | - /* |
---|
7188 | | - * For each potential GPU frequency, load a ring frequency we'd like |
---|
7189 | | - * to use for memory access. We do this by specifying the IA frequency |
---|
7190 | | - * the PCU should use as a reference to determine the ring frequency. |
---|
7191 | | - */ |
---|
7192 | | - for (gpu_freq = max_gpu_freq; gpu_freq >= min_gpu_freq; gpu_freq--) { |
---|
7193 | | - const int diff = max_gpu_freq - gpu_freq; |
---|
7194 | | - unsigned int ia_freq = 0, ring_freq = 0; |
---|
7195 | | - |
---|
7196 | | - if (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) { |
---|
7197 | | - /* |
---|
7198 | | - * ring_freq = 2 * GT. ring_freq is in 100MHz units |
---|
7199 | | - * No floor required for ring frequency on SKL. |
---|
7200 | | - */ |
---|
7201 | | - ring_freq = gpu_freq; |
---|
7202 | | - } else if (INTEL_GEN(dev_priv) >= 8) { |
---|
7203 | | - /* max(2 * GT, DDR). NB: GT is 50MHz units */ |
---|
7204 | | - ring_freq = max(min_ring_freq, gpu_freq); |
---|
7205 | | - } else if (IS_HASWELL(dev_priv)) { |
---|
7206 | | - ring_freq = mult_frac(gpu_freq, 5, 4); |
---|
7207 | | - ring_freq = max(min_ring_freq, ring_freq); |
---|
7208 | | - /* leave ia_freq as the default, chosen by cpufreq */ |
---|
7209 | | - } else { |
---|
7210 | | - /* On older processors, there is no separate ring |
---|
7211 | | - * clock domain, so in order to boost the bandwidth |
---|
7212 | | - * of the ring, we need to upclock the CPU (ia_freq). |
---|
7213 | | - * |
---|
7214 | | - * For GPU frequencies less than 750MHz, |
---|
7215 | | - * just use the lowest ring freq. |
---|
7216 | | - */ |
---|
7217 | | - if (gpu_freq < min_freq) |
---|
7218 | | - ia_freq = 800; |
---|
7219 | | - else |
---|
7220 | | - ia_freq = max_ia_freq - ((diff * scaling_factor) / 2); |
---|
7221 | | - ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100); |
---|
7222 | | - } |
---|
7223 | | - |
---|
7224 | | - sandybridge_pcode_write(dev_priv, |
---|
7225 | | - GEN6_PCODE_WRITE_MIN_FREQ_TABLE, |
---|
7226 | | - ia_freq << GEN6_PCODE_FREQ_IA_RATIO_SHIFT | |
---|
7227 | | - ring_freq << GEN6_PCODE_FREQ_RING_RATIO_SHIFT | |
---|
7228 | | - gpu_freq); |
---|
7229 | | - } |
---|
7230 | | -} |
---|
7231 | | - |
---|
7232 | | -static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv) |
---|
7233 | | -{ |
---|
7234 | | - u32 val, rp0; |
---|
7235 | | - |
---|
7236 | | - val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); |
---|
7237 | | - |
---|
7238 | | - switch (INTEL_INFO(dev_priv)->sseu.eu_total) { |
---|
7239 | | - case 8: |
---|
7240 | | - /* (2 * 4) config */ |
---|
7241 | | - rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT); |
---|
7242 | | - break; |
---|
7243 | | - case 12: |
---|
7244 | | - /* (2 * 6) config */ |
---|
7245 | | - rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT); |
---|
7246 | | - break; |
---|
7247 | | - case 16: |
---|
7248 | | - /* (2 * 8) config */ |
---|
7249 | | - default: |
---|
7250 | | - /* Setting (2 * 8) Min RP0 for any other combination */ |
---|
7251 | | - rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT); |
---|
7252 | | - break; |
---|
7253 | | - } |
---|
7254 | | - |
---|
7255 | | - rp0 = (rp0 & FB_GFX_FREQ_FUSE_MASK); |
---|
7256 | | - |
---|
7257 | | - return rp0; |
---|
7258 | | -} |
---|
7259 | | - |
---|
7260 | | -static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv) |
---|
7261 | | -{ |
---|
7262 | | - u32 val, rpe; |
---|
7263 | | - |
---|
7264 | | - val = vlv_punit_read(dev_priv, PUNIT_GPU_DUTYCYCLE_REG); |
---|
7265 | | - rpe = (val >> PUNIT_GPU_DUTYCYCLE_RPE_FREQ_SHIFT) & PUNIT_GPU_DUTYCYCLE_RPE_FREQ_MASK; |
---|
7266 | | - |
---|
7267 | | - return rpe; |
---|
7268 | | -} |
---|
7269 | | - |
---|
7270 | | -static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv) |
---|
7271 | | -{ |
---|
7272 | | - u32 val, rp1; |
---|
7273 | | - |
---|
7274 | | - val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); |
---|
7275 | | - rp1 = (val & FB_GFX_FREQ_FUSE_MASK); |
---|
7276 | | - |
---|
7277 | | - return rp1; |
---|
7278 | | -} |
---|
7279 | | - |
---|
7280 | | -static u32 cherryview_rps_min_freq(struct drm_i915_private *dev_priv) |
---|
7281 | | -{ |
---|
7282 | | - u32 val, rpn; |
---|
7283 | | - |
---|
7284 | | - val = vlv_punit_read(dev_priv, FB_GFX_FMIN_AT_VMIN_FUSE); |
---|
7285 | | - rpn = ((val >> FB_GFX_FMIN_AT_VMIN_FUSE_SHIFT) & |
---|
7286 | | - FB_GFX_FREQ_FUSE_MASK); |
---|
7287 | | - |
---|
7288 | | - return rpn; |
---|
7289 | | -} |
---|
7290 | | - |
---|
7291 | | -static int valleyview_rps_guar_freq(struct drm_i915_private *dev_priv) |
---|
7292 | | -{ |
---|
7293 | | - u32 val, rp1; |
---|
7294 | | - |
---|
7295 | | - val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE); |
---|
7296 | | - |
---|
7297 | | - rp1 = (val & FB_GFX_FGUARANTEED_FREQ_FUSE_MASK) >> FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT; |
---|
7298 | | - |
---|
7299 | | - return rp1; |
---|
7300 | | -} |
---|
7301 | | - |
---|
7302 | | -static int valleyview_rps_max_freq(struct drm_i915_private *dev_priv) |
---|
7303 | | -{ |
---|
7304 | | - u32 val, rp0; |
---|
7305 | | - |
---|
7306 | | - val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE); |
---|
7307 | | - |
---|
7308 | | - rp0 = (val & FB_GFX_MAX_FREQ_FUSE_MASK) >> FB_GFX_MAX_FREQ_FUSE_SHIFT; |
---|
7309 | | - /* Clamp to max */ |
---|
7310 | | - rp0 = min_t(u32, rp0, 0xea); |
---|
7311 | | - |
---|
7312 | | - return rp0; |
---|
7313 | | -} |
---|
7314 | | - |
---|
7315 | | -static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv) |
---|
7316 | | -{ |
---|
7317 | | - u32 val, rpe; |
---|
7318 | | - |
---|
7319 | | - val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_LO); |
---|
7320 | | - rpe = (val & FB_FMAX_VMIN_FREQ_LO_MASK) >> FB_FMAX_VMIN_FREQ_LO_SHIFT; |
---|
7321 | | - val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_HI); |
---|
7322 | | - rpe |= (val & FB_FMAX_VMIN_FREQ_HI_MASK) << 5; |
---|
7323 | | - |
---|
7324 | | - return rpe; |
---|
7325 | | -} |
---|
7326 | | - |
---|
7327 | | -static int valleyview_rps_min_freq(struct drm_i915_private *dev_priv) |
---|
7328 | | -{ |
---|
7329 | | - u32 val; |
---|
7330 | | - |
---|
7331 | | - val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff; |
---|
7332 | | - /* |
---|
7333 | | - * According to the BYT Punit GPU turbo HAS 1.1.6.3 the minimum value |
---|
7334 | | - * for the minimum frequency in GPLL mode is 0xc1. Contrary to this on |
---|
7335 | | - * a BYT-M B0 the above register contains 0xbf. Moreover when setting |
---|
7336 | | - * a frequency Punit will not allow values below 0xc0. Clamp it 0xc0 |
---|
7337 | | - * to make sure it matches what Punit accepts. |
---|
7338 | | - */ |
---|
7339 | | - return max_t(u32, val, 0xc0); |
---|
7340 | | -} |
---|
7341 | | - |
---|
7342 | | -/* Check that the pctx buffer wasn't move under us. */ |
---|
7343 | | -static void valleyview_check_pctx(struct drm_i915_private *dev_priv) |
---|
7344 | | -{ |
---|
7345 | | - unsigned long pctx_addr = I915_READ(VLV_PCBR) & ~4095; |
---|
7346 | | - |
---|
7347 | | - WARN_ON(pctx_addr != dev_priv->dsm.start + |
---|
7348 | | - dev_priv->vlv_pctx->stolen->start); |
---|
7349 | | -} |
---|
7350 | | - |
---|
7351 | | - |
---|
7352 | | -/* Check that the pcbr address is not empty. */ |
---|
7353 | | -static void cherryview_check_pctx(struct drm_i915_private *dev_priv) |
---|
7354 | | -{ |
---|
7355 | | - unsigned long pctx_addr = I915_READ(VLV_PCBR) & ~4095; |
---|
7356 | | - |
---|
7357 | | - WARN_ON((pctx_addr >> VLV_PCBR_ADDR_SHIFT) == 0); |
---|
7358 | | -} |
---|
7359 | | - |
---|
7360 | | -static void cherryview_setup_pctx(struct drm_i915_private *dev_priv) |
---|
7361 | | -{ |
---|
7362 | | - resource_size_t pctx_paddr, paddr; |
---|
7363 | | - resource_size_t pctx_size = 32*1024; |
---|
7364 | | - u32 pcbr; |
---|
7365 | | - |
---|
7366 | | - pcbr = I915_READ(VLV_PCBR); |
---|
7367 | | - if ((pcbr >> VLV_PCBR_ADDR_SHIFT) == 0) { |
---|
7368 | | - DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n"); |
---|
7369 | | - paddr = dev_priv->dsm.end + 1 - pctx_size; |
---|
7370 | | - GEM_BUG_ON(paddr > U32_MAX); |
---|
7371 | | - |
---|
7372 | | - pctx_paddr = (paddr & (~4095)); |
---|
7373 | | - I915_WRITE(VLV_PCBR, pctx_paddr); |
---|
7374 | | - } |
---|
7375 | | - |
---|
7376 | | - DRM_DEBUG_DRIVER("PCBR: 0x%08x\n", I915_READ(VLV_PCBR)); |
---|
7377 | | -} |
---|
7378 | | - |
---|
7379 | | -static void valleyview_setup_pctx(struct drm_i915_private *dev_priv) |
---|
7380 | | -{ |
---|
7381 | | - struct drm_i915_gem_object *pctx; |
---|
7382 | | - resource_size_t pctx_paddr; |
---|
7383 | | - resource_size_t pctx_size = 24*1024; |
---|
7384 | | - u32 pcbr; |
---|
7385 | | - |
---|
7386 | | - pcbr = I915_READ(VLV_PCBR); |
---|
7387 | | - if (pcbr) { |
---|
7388 | | - /* BIOS set it up already, grab the pre-alloc'd space */ |
---|
7389 | | - resource_size_t pcbr_offset; |
---|
7390 | | - |
---|
7391 | | - pcbr_offset = (pcbr & (~4095)) - dev_priv->dsm.start; |
---|
7392 | | - pctx = i915_gem_object_create_stolen_for_preallocated(dev_priv, |
---|
7393 | | - pcbr_offset, |
---|
7394 | | - I915_GTT_OFFSET_NONE, |
---|
7395 | | - pctx_size); |
---|
7396 | | - goto out; |
---|
7397 | | - } |
---|
7398 | | - |
---|
7399 | | - DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n"); |
---|
7400 | | - |
---|
7401 | | - /* |
---|
7402 | | - * From the Gunit register HAS: |
---|
7403 | | - * The Gfx driver is expected to program this register and ensure |
---|
7404 | | - * proper allocation within Gfx stolen memory. For example, this |
---|
7405 | | - * register should be programmed such than the PCBR range does not |
---|
7406 | | - * overlap with other ranges, such as the frame buffer, protected |
---|
7407 | | - * memory, or any other relevant ranges. |
---|
7408 | | - */ |
---|
7409 | | - pctx = i915_gem_object_create_stolen(dev_priv, pctx_size); |
---|
7410 | | - if (!pctx) { |
---|
7411 | | - DRM_DEBUG("not enough stolen space for PCTX, disabling\n"); |
---|
7412 | | - goto out; |
---|
7413 | | - } |
---|
7414 | | - |
---|
7415 | | - GEM_BUG_ON(range_overflows_t(u64, |
---|
7416 | | - dev_priv->dsm.start, |
---|
7417 | | - pctx->stolen->start, |
---|
7418 | | - U32_MAX)); |
---|
7419 | | - pctx_paddr = dev_priv->dsm.start + pctx->stolen->start; |
---|
7420 | | - I915_WRITE(VLV_PCBR, pctx_paddr); |
---|
7421 | | - |
---|
7422 | | -out: |
---|
7423 | | - DRM_DEBUG_DRIVER("PCBR: 0x%08x\n", I915_READ(VLV_PCBR)); |
---|
7424 | | - dev_priv->vlv_pctx = pctx; |
---|
7425 | | -} |
---|
7426 | | - |
---|
7427 | | -static void valleyview_cleanup_pctx(struct drm_i915_private *dev_priv) |
---|
7428 | | -{ |
---|
7429 | | - struct drm_i915_gem_object *pctx; |
---|
7430 | | - |
---|
7431 | | - pctx = fetch_and_zero(&dev_priv->vlv_pctx); |
---|
7432 | | - if (pctx) |
---|
7433 | | - i915_gem_object_put(pctx); |
---|
7434 | | -} |
---|
7435 | | - |
---|
7436 | | -static void vlv_init_gpll_ref_freq(struct drm_i915_private *dev_priv) |
---|
7437 | | -{ |
---|
7438 | | - dev_priv->gt_pm.rps.gpll_ref_freq = |
---|
7439 | | - vlv_get_cck_clock(dev_priv, "GPLL ref", |
---|
7440 | | - CCK_GPLL_CLOCK_CONTROL, |
---|
7441 | | - dev_priv->czclk_freq); |
---|
7442 | | - |
---|
7443 | | - DRM_DEBUG_DRIVER("GPLL reference freq: %d kHz\n", |
---|
7444 | | - dev_priv->gt_pm.rps.gpll_ref_freq); |
---|
7445 | | -} |
---|
7446 | | - |
---|
7447 | | -static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv) |
---|
7448 | | -{ |
---|
7449 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
7450 | | - u32 val; |
---|
7451 | | - |
---|
7452 | | - valleyview_setup_pctx(dev_priv); |
---|
7453 | | - |
---|
7454 | | - vlv_init_gpll_ref_freq(dev_priv); |
---|
7455 | | - |
---|
7456 | | - val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); |
---|
7457 | | - switch ((val >> 6) & 3) { |
---|
7458 | | - case 0: |
---|
7459 | | - case 1: |
---|
7460 | | - dev_priv->mem_freq = 800; |
---|
7461 | | - break; |
---|
7462 | | - case 2: |
---|
7463 | | - dev_priv->mem_freq = 1066; |
---|
7464 | | - break; |
---|
7465 | | - case 3: |
---|
7466 | | - dev_priv->mem_freq = 1333; |
---|
7467 | | - break; |
---|
7468 | | - } |
---|
7469 | | - DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); |
---|
7470 | | - |
---|
7471 | | - rps->max_freq = valleyview_rps_max_freq(dev_priv); |
---|
7472 | | - rps->rp0_freq = rps->max_freq; |
---|
7473 | | - DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", |
---|
7474 | | - intel_gpu_freq(dev_priv, rps->max_freq), |
---|
7475 | | - rps->max_freq); |
---|
7476 | | - |
---|
7477 | | - rps->efficient_freq = valleyview_rps_rpe_freq(dev_priv); |
---|
7478 | | - DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", |
---|
7479 | | - intel_gpu_freq(dev_priv, rps->efficient_freq), |
---|
7480 | | - rps->efficient_freq); |
---|
7481 | | - |
---|
7482 | | - rps->rp1_freq = valleyview_rps_guar_freq(dev_priv); |
---|
7483 | | - DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n", |
---|
7484 | | - intel_gpu_freq(dev_priv, rps->rp1_freq), |
---|
7485 | | - rps->rp1_freq); |
---|
7486 | | - |
---|
7487 | | - rps->min_freq = valleyview_rps_min_freq(dev_priv); |
---|
7488 | | - DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", |
---|
7489 | | - intel_gpu_freq(dev_priv, rps->min_freq), |
---|
7490 | | - rps->min_freq); |
---|
7491 | | -} |
---|
7492 | | - |
---|
7493 | | -static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv) |
---|
7494 | | -{ |
---|
7495 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
7496 | | - u32 val; |
---|
7497 | | - |
---|
7498 | | - cherryview_setup_pctx(dev_priv); |
---|
7499 | | - |
---|
7500 | | - vlv_init_gpll_ref_freq(dev_priv); |
---|
7501 | | - |
---|
7502 | | - mutex_lock(&dev_priv->sb_lock); |
---|
7503 | | - val = vlv_cck_read(dev_priv, CCK_FUSE_REG); |
---|
7504 | | - mutex_unlock(&dev_priv->sb_lock); |
---|
7505 | | - |
---|
7506 | | - switch ((val >> 2) & 0x7) { |
---|
7507 | | - case 3: |
---|
7508 | | - dev_priv->mem_freq = 2000; |
---|
7509 | | - break; |
---|
7510 | | - default: |
---|
7511 | | - dev_priv->mem_freq = 1600; |
---|
7512 | | - break; |
---|
7513 | | - } |
---|
7514 | | - DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); |
---|
7515 | | - |
---|
7516 | | - rps->max_freq = cherryview_rps_max_freq(dev_priv); |
---|
7517 | | - rps->rp0_freq = rps->max_freq; |
---|
7518 | | - DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", |
---|
7519 | | - intel_gpu_freq(dev_priv, rps->max_freq), |
---|
7520 | | - rps->max_freq); |
---|
7521 | | - |
---|
7522 | | - rps->efficient_freq = cherryview_rps_rpe_freq(dev_priv); |
---|
7523 | | - DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", |
---|
7524 | | - intel_gpu_freq(dev_priv, rps->efficient_freq), |
---|
7525 | | - rps->efficient_freq); |
---|
7526 | | - |
---|
7527 | | - rps->rp1_freq = cherryview_rps_guar_freq(dev_priv); |
---|
7528 | | - DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n", |
---|
7529 | | - intel_gpu_freq(dev_priv, rps->rp1_freq), |
---|
7530 | | - rps->rp1_freq); |
---|
7531 | | - |
---|
7532 | | - rps->min_freq = cherryview_rps_min_freq(dev_priv); |
---|
7533 | | - DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", |
---|
7534 | | - intel_gpu_freq(dev_priv, rps->min_freq), |
---|
7535 | | - rps->min_freq); |
---|
7536 | | - |
---|
7537 | | - WARN_ONCE((rps->max_freq | rps->efficient_freq | rps->rp1_freq | |
---|
7538 | | - rps->min_freq) & 1, |
---|
7539 | | - "Odd GPU freq values\n"); |
---|
7540 | | -} |
---|
7541 | | - |
---|
7542 | | -static void valleyview_cleanup_gt_powersave(struct drm_i915_private *dev_priv) |
---|
7543 | | -{ |
---|
7544 | | - valleyview_cleanup_pctx(dev_priv); |
---|
7545 | | -} |
---|
7546 | | - |
---|
7547 | | -static void cherryview_enable_rc6(struct drm_i915_private *dev_priv) |
---|
7548 | | -{ |
---|
7549 | | - struct intel_engine_cs *engine; |
---|
7550 | | - enum intel_engine_id id; |
---|
7551 | | - u32 gtfifodbg, rc6_mode, pcbr; |
---|
7552 | | - |
---|
7553 | | - gtfifodbg = I915_READ(GTFIFODBG) & ~(GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV | |
---|
7554 | | - GT_FIFO_FREE_ENTRIES_CHV); |
---|
7555 | | - if (gtfifodbg) { |
---|
7556 | | - DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n", |
---|
7557 | | - gtfifodbg); |
---|
7558 | | - I915_WRITE(GTFIFODBG, gtfifodbg); |
---|
7559 | | - } |
---|
7560 | | - |
---|
7561 | | - cherryview_check_pctx(dev_priv); |
---|
7562 | | - |
---|
7563 | | - /* 1a & 1b: Get forcewake during program sequence. Although the driver |
---|
7564 | | - * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ |
---|
7565 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
---|
7566 | | - |
---|
7567 | | - /* Disable RC states. */ |
---|
7568 | | - I915_WRITE(GEN6_RC_CONTROL, 0); |
---|
7569 | | - |
---|
7570 | | - /* 2a: Program RC6 thresholds.*/ |
---|
7571 | | - I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); |
---|
7572 | | - I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ |
---|
7573 | | - I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ |
---|
7574 | | - |
---|
7575 | | - for_each_engine(engine, dev_priv, id) |
---|
7576 | | - I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); |
---|
7577 | | - I915_WRITE(GEN6_RC_SLEEP, 0); |
---|
7578 | | - |
---|
7579 | | - /* TO threshold set to 500 us ( 0x186 * 1.28 us) */ |
---|
7580 | | - I915_WRITE(GEN6_RC6_THRESHOLD, 0x186); |
---|
7581 | | - |
---|
7582 | | - /* Allows RC6 residency counter to work */ |
---|
7583 | | - I915_WRITE(VLV_COUNTER_CONTROL, |
---|
7584 | | - _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH | |
---|
7585 | | - VLV_MEDIA_RC6_COUNT_EN | |
---|
7586 | | - VLV_RENDER_RC6_COUNT_EN)); |
---|
7587 | | - |
---|
7588 | | - /* For now we assume BIOS is allocating and populating the PCBR */ |
---|
7589 | | - pcbr = I915_READ(VLV_PCBR); |
---|
7590 | | - |
---|
7591 | | - /* 3: Enable RC6 */ |
---|
7592 | | - rc6_mode = 0; |
---|
7593 | | - if (pcbr >> VLV_PCBR_ADDR_SHIFT) |
---|
7594 | | - rc6_mode = GEN7_RC_CTL_TO_MODE; |
---|
7595 | | - I915_WRITE(GEN6_RC_CONTROL, rc6_mode); |
---|
7596 | | - |
---|
7597 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
---|
7598 | | -} |
---|
7599 | | - |
---|
7600 | | -static void cherryview_enable_rps(struct drm_i915_private *dev_priv) |
---|
7601 | | -{ |
---|
7602 | | - u32 val; |
---|
7603 | | - |
---|
7604 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
---|
7605 | | - |
---|
7606 | | - /* 1: Program defaults and thresholds for RPS*/ |
---|
7607 | | - I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); |
---|
7608 | | - I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); |
---|
7609 | | - I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); |
---|
7610 | | - I915_WRITE(GEN6_RP_UP_EI, 66000); |
---|
7611 | | - I915_WRITE(GEN6_RP_DOWN_EI, 350000); |
---|
7612 | | - |
---|
7613 | | - I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
---|
7614 | | - |
---|
7615 | | - /* 2: Enable RPS */ |
---|
7616 | | - I915_WRITE(GEN6_RP_CONTROL, |
---|
7617 | | - GEN6_RP_MEDIA_HW_NORMAL_MODE | |
---|
7618 | | - GEN6_RP_MEDIA_IS_GFX | |
---|
7619 | | - GEN6_RP_ENABLE | |
---|
7620 | | - GEN6_RP_UP_BUSY_AVG | |
---|
7621 | | - GEN6_RP_DOWN_IDLE_AVG); |
---|
7622 | | - |
---|
7623 | | - /* Setting Fixed Bias */ |
---|
7624 | | - val = VLV_OVERRIDE_EN | |
---|
7625 | | - VLV_SOC_TDP_EN | |
---|
7626 | | - CHV_BIAS_CPU_50_SOC_50; |
---|
7627 | | - vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val); |
---|
7628 | | - |
---|
7629 | | - val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); |
---|
7630 | | - |
---|
7631 | | - /* RPS code assumes GPLL is used */ |
---|
7632 | | - WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n"); |
---|
7633 | | - |
---|
7634 | | - DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE)); |
---|
7635 | | - DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); |
---|
7636 | | - |
---|
7637 | | - reset_rps(dev_priv, valleyview_set_rps); |
---|
7638 | | - |
---|
7639 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
---|
7640 | | -} |
---|
7641 | | - |
---|
7642 | | -static void valleyview_enable_rc6(struct drm_i915_private *dev_priv) |
---|
7643 | | -{ |
---|
7644 | | - struct intel_engine_cs *engine; |
---|
7645 | | - enum intel_engine_id id; |
---|
7646 | | - u32 gtfifodbg; |
---|
7647 | | - |
---|
7648 | | - valleyview_check_pctx(dev_priv); |
---|
7649 | | - |
---|
7650 | | - gtfifodbg = I915_READ(GTFIFODBG); |
---|
7651 | | - if (gtfifodbg) { |
---|
7652 | | - DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n", |
---|
7653 | | - gtfifodbg); |
---|
7654 | | - I915_WRITE(GTFIFODBG, gtfifodbg); |
---|
7655 | | - } |
---|
7656 | | - |
---|
7657 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
---|
7658 | | - |
---|
7659 | | - /* Disable RC states. */ |
---|
7660 | | - I915_WRITE(GEN6_RC_CONTROL, 0); |
---|
7661 | | - |
---|
7662 | | - I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 0x00280000); |
---|
7663 | | - I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); |
---|
7664 | | - I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); |
---|
7665 | | - |
---|
7666 | | - for_each_engine(engine, dev_priv, id) |
---|
7667 | | - I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); |
---|
7668 | | - |
---|
7669 | | - I915_WRITE(GEN6_RC6_THRESHOLD, 0x557); |
---|
7670 | | - |
---|
7671 | | - /* Allows RC6 residency counter to work */ |
---|
7672 | | - I915_WRITE(VLV_COUNTER_CONTROL, |
---|
7673 | | - _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH | |
---|
7674 | | - VLV_MEDIA_RC0_COUNT_EN | |
---|
7675 | | - VLV_RENDER_RC0_COUNT_EN | |
---|
7676 | | - VLV_MEDIA_RC6_COUNT_EN | |
---|
7677 | | - VLV_RENDER_RC6_COUNT_EN)); |
---|
7678 | | - |
---|
7679 | | - I915_WRITE(GEN6_RC_CONTROL, |
---|
7680 | | - GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL); |
---|
7681 | | - |
---|
7682 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
---|
7683 | | -} |
---|
7684 | | - |
---|
7685 | | -static void valleyview_enable_rps(struct drm_i915_private *dev_priv) |
---|
7686 | | -{ |
---|
7687 | | - u32 val; |
---|
7688 | | - |
---|
7689 | | - intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); |
---|
7690 | | - |
---|
7691 | | - I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); |
---|
7692 | | - I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); |
---|
7693 | | - I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); |
---|
7694 | | - I915_WRITE(GEN6_RP_UP_EI, 66000); |
---|
7695 | | - I915_WRITE(GEN6_RP_DOWN_EI, 350000); |
---|
7696 | | - |
---|
7697 | | - I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
---|
7698 | | - |
---|
7699 | | - I915_WRITE(GEN6_RP_CONTROL, |
---|
7700 | | - GEN6_RP_MEDIA_TURBO | |
---|
7701 | | - GEN6_RP_MEDIA_HW_NORMAL_MODE | |
---|
7702 | | - GEN6_RP_MEDIA_IS_GFX | |
---|
7703 | | - GEN6_RP_ENABLE | |
---|
7704 | | - GEN6_RP_UP_BUSY_AVG | |
---|
7705 | | - GEN6_RP_DOWN_IDLE_CONT); |
---|
7706 | | - |
---|
7707 | | - /* Setting Fixed Bias */ |
---|
7708 | | - val = VLV_OVERRIDE_EN | |
---|
7709 | | - VLV_SOC_TDP_EN | |
---|
7710 | | - VLV_BIAS_CPU_125_SOC_875; |
---|
7711 | | - vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val); |
---|
7712 | | - |
---|
7713 | | - val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); |
---|
7714 | | - |
---|
7715 | | - /* RPS code assumes GPLL is used */ |
---|
7716 | | - WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n"); |
---|
7717 | | - |
---|
7718 | | - DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE)); |
---|
7719 | | - DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val); |
---|
7720 | | - |
---|
7721 | | - reset_rps(dev_priv, valleyview_set_rps); |
---|
7722 | | - |
---|
7723 | | - intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); |
---|
7724 | | -} |
---|
7725 | | - |
---|
7726 | | -static unsigned long intel_pxfreq(u32 vidfreq) |
---|
7727 | | -{ |
---|
7728 | | - unsigned long freq; |
---|
7729 | | - int div = (vidfreq & 0x3f0000) >> 16; |
---|
7730 | | - int post = (vidfreq & 0x3000) >> 12; |
---|
7731 | | - int pre = (vidfreq & 0x7); |
---|
7732 | | - |
---|
7733 | | - if (!pre) |
---|
7734 | | - return 0; |
---|
7735 | | - |
---|
7736 | | - freq = ((div * 133333) / ((1<<post) * pre)); |
---|
7737 | | - |
---|
7738 | | - return freq; |
---|
7739 | | -} |
---|
7740 | | - |
---|
7741 | | -static const struct cparams { |
---|
7742 | | - u16 i; |
---|
7743 | | - u16 t; |
---|
7744 | | - u16 m; |
---|
7745 | | - u16 c; |
---|
7746 | | -} cparams[] = { |
---|
7747 | | - { 1, 1333, 301, 28664 }, |
---|
7748 | | - { 1, 1066, 294, 24460 }, |
---|
7749 | | - { 1, 800, 294, 25192 }, |
---|
7750 | | - { 0, 1333, 276, 27605 }, |
---|
7751 | | - { 0, 1066, 276, 27605 }, |
---|
7752 | | - { 0, 800, 231, 23784 }, |
---|
7753 | | -}; |
---|
7754 | | - |
---|
7755 | | -static unsigned long __i915_chipset_val(struct drm_i915_private *dev_priv) |
---|
7756 | | -{ |
---|
7757 | | - u64 total_count, diff, ret; |
---|
7758 | | - u32 count1, count2, count3, m = 0, c = 0; |
---|
7759 | | - unsigned long now = jiffies_to_msecs(jiffies), diff1; |
---|
7760 | | - int i; |
---|
7761 | | - |
---|
7762 | | - lockdep_assert_held(&mchdev_lock); |
---|
7763 | | - |
---|
7764 | | - diff1 = now - dev_priv->ips.last_time1; |
---|
7765 | | - |
---|
7766 | | - /* Prevent division-by-zero if we are asking too fast. |
---|
7767 | | - * Also, we don't get interesting results if we are polling |
---|
7768 | | - * faster than once in 10ms, so just return the saved value |
---|
7769 | | - * in such cases. |
---|
7770 | | - */ |
---|
7771 | | - if (diff1 <= 10) |
---|
7772 | | - return dev_priv->ips.chipset_power; |
---|
7773 | | - |
---|
7774 | | - count1 = I915_READ(DMIEC); |
---|
7775 | | - count2 = I915_READ(DDREC); |
---|
7776 | | - count3 = I915_READ(CSIEC); |
---|
7777 | | - |
---|
7778 | | - total_count = count1 + count2 + count3; |
---|
7779 | | - |
---|
7780 | | - /* FIXME: handle per-counter overflow */ |
---|
7781 | | - if (total_count < dev_priv->ips.last_count1) { |
---|
7782 | | - diff = ~0UL - dev_priv->ips.last_count1; |
---|
7783 | | - diff += total_count; |
---|
7784 | | - } else { |
---|
7785 | | - diff = total_count - dev_priv->ips.last_count1; |
---|
7786 | | - } |
---|
7787 | | - |
---|
7788 | | - for (i = 0; i < ARRAY_SIZE(cparams); i++) { |
---|
7789 | | - if (cparams[i].i == dev_priv->ips.c_m && |
---|
7790 | | - cparams[i].t == dev_priv->ips.r_t) { |
---|
7791 | | - m = cparams[i].m; |
---|
7792 | | - c = cparams[i].c; |
---|
7793 | | - break; |
---|
7794 | | - } |
---|
7795 | | - } |
---|
7796 | | - |
---|
7797 | | - diff = div_u64(diff, diff1); |
---|
7798 | | - ret = ((m * diff) + c); |
---|
7799 | | - ret = div_u64(ret, 10); |
---|
7800 | | - |
---|
7801 | | - dev_priv->ips.last_count1 = total_count; |
---|
7802 | | - dev_priv->ips.last_time1 = now; |
---|
7803 | | - |
---|
7804 | | - dev_priv->ips.chipset_power = ret; |
---|
7805 | | - |
---|
7806 | | - return ret; |
---|
7807 | | -} |
---|
7808 | | - |
---|
7809 | | -unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) |
---|
7810 | | -{ |
---|
7811 | | - unsigned long val; |
---|
7812 | | - |
---|
7813 | | - if (!IS_GEN5(dev_priv)) |
---|
7814 | | - return 0; |
---|
7815 | | - |
---|
7816 | | - spin_lock_irq(&mchdev_lock); |
---|
7817 | | - |
---|
7818 | | - val = __i915_chipset_val(dev_priv); |
---|
7819 | | - |
---|
7820 | | - spin_unlock_irq(&mchdev_lock); |
---|
7821 | | - |
---|
7822 | | - return val; |
---|
7823 | | -} |
---|
7824 | | - |
---|
7825 | | -unsigned long i915_mch_val(struct drm_i915_private *dev_priv) |
---|
7826 | | -{ |
---|
7827 | | - unsigned long m, x, b; |
---|
7828 | | - u32 tsfs; |
---|
7829 | | - |
---|
7830 | | - tsfs = I915_READ(TSFS); |
---|
7831 | | - |
---|
7832 | | - m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT); |
---|
7833 | | - x = I915_READ8(TR1); |
---|
7834 | | - |
---|
7835 | | - b = tsfs & TSFS_INTR_MASK; |
---|
7836 | | - |
---|
7837 | | - return ((m * x) / 127) - b; |
---|
7838 | | -} |
---|
7839 | | - |
---|
7840 | | -static int _pxvid_to_vd(u8 pxvid) |
---|
7841 | | -{ |
---|
7842 | | - if (pxvid == 0) |
---|
7843 | | - return 0; |
---|
7844 | | - |
---|
7845 | | - if (pxvid >= 8 && pxvid < 31) |
---|
7846 | | - pxvid = 31; |
---|
7847 | | - |
---|
7848 | | - return (pxvid + 2) * 125; |
---|
7849 | | -} |
---|
7850 | | - |
---|
7851 | | -static u32 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) |
---|
7852 | | -{ |
---|
7853 | | - const int vd = _pxvid_to_vd(pxvid); |
---|
7854 | | - const int vm = vd - 1125; |
---|
7855 | | - |
---|
7856 | | - if (INTEL_INFO(dev_priv)->is_mobile) |
---|
7857 | | - return vm > 0 ? vm : 0; |
---|
7858 | | - |
---|
7859 | | - return vd; |
---|
7860 | | -} |
---|
7861 | | - |
---|
7862 | | -static void __i915_update_gfx_val(struct drm_i915_private *dev_priv) |
---|
7863 | | -{ |
---|
7864 | | - u64 now, diff, diffms; |
---|
7865 | | - u32 count; |
---|
7866 | | - |
---|
7867 | | - lockdep_assert_held(&mchdev_lock); |
---|
7868 | | - |
---|
7869 | | - now = ktime_get_raw_ns(); |
---|
7870 | | - diffms = now - dev_priv->ips.last_time2; |
---|
7871 | | - do_div(diffms, NSEC_PER_MSEC); |
---|
7872 | | - |
---|
7873 | | - /* Don't divide by 0 */ |
---|
7874 | | - if (!diffms) |
---|
7875 | | - return; |
---|
7876 | | - |
---|
7877 | | - count = I915_READ(GFXEC); |
---|
7878 | | - |
---|
7879 | | - if (count < dev_priv->ips.last_count2) { |
---|
7880 | | - diff = ~0UL - dev_priv->ips.last_count2; |
---|
7881 | | - diff += count; |
---|
7882 | | - } else { |
---|
7883 | | - diff = count - dev_priv->ips.last_count2; |
---|
7884 | | - } |
---|
7885 | | - |
---|
7886 | | - dev_priv->ips.last_count2 = count; |
---|
7887 | | - dev_priv->ips.last_time2 = now; |
---|
7888 | | - |
---|
7889 | | - /* More magic constants... */ |
---|
7890 | | - diff = diff * 1181; |
---|
7891 | | - diff = div_u64(diff, diffms * 10); |
---|
7892 | | - dev_priv->ips.gfx_power = diff; |
---|
7893 | | -} |
---|
7894 | | - |
---|
7895 | | -void i915_update_gfx_val(struct drm_i915_private *dev_priv) |
---|
7896 | | -{ |
---|
7897 | | - if (!IS_GEN5(dev_priv)) |
---|
7898 | | - return; |
---|
7899 | | - |
---|
7900 | | - spin_lock_irq(&mchdev_lock); |
---|
7901 | | - |
---|
7902 | | - __i915_update_gfx_val(dev_priv); |
---|
7903 | | - |
---|
7904 | | - spin_unlock_irq(&mchdev_lock); |
---|
7905 | | -} |
---|
7906 | | - |
---|
7907 | | -static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv) |
---|
7908 | | -{ |
---|
7909 | | - unsigned long t, corr, state1, corr2, state2; |
---|
7910 | | - u32 pxvid, ext_v; |
---|
7911 | | - |
---|
7912 | | - lockdep_assert_held(&mchdev_lock); |
---|
7913 | | - |
---|
7914 | | - pxvid = I915_READ(PXVFREQ(dev_priv->gt_pm.rps.cur_freq)); |
---|
7915 | | - pxvid = (pxvid >> 24) & 0x7f; |
---|
7916 | | - ext_v = pvid_to_extvid(dev_priv, pxvid); |
---|
7917 | | - |
---|
7918 | | - state1 = ext_v; |
---|
7919 | | - |
---|
7920 | | - t = i915_mch_val(dev_priv); |
---|
7921 | | - |
---|
7922 | | - /* Revel in the empirically derived constants */ |
---|
7923 | | - |
---|
7924 | | - /* Correction factor in 1/100000 units */ |
---|
7925 | | - if (t > 80) |
---|
7926 | | - corr = ((t * 2349) + 135940); |
---|
7927 | | - else if (t >= 50) |
---|
7928 | | - corr = ((t * 964) + 29317); |
---|
7929 | | - else /* < 50 */ |
---|
7930 | | - corr = ((t * 301) + 1004); |
---|
7931 | | - |
---|
7932 | | - corr = corr * ((150142 * state1) / 10000 - 78642); |
---|
7933 | | - corr /= 100000; |
---|
7934 | | - corr2 = (corr * dev_priv->ips.corr); |
---|
7935 | | - |
---|
7936 | | - state2 = (corr2 * state1) / 10000; |
---|
7937 | | - state2 /= 100; /* convert to mW */ |
---|
7938 | | - |
---|
7939 | | - __i915_update_gfx_val(dev_priv); |
---|
7940 | | - |
---|
7941 | | - return dev_priv->ips.gfx_power + state2; |
---|
7942 | | -} |
---|
7943 | | - |
---|
7944 | | -unsigned long i915_gfx_val(struct drm_i915_private *dev_priv) |
---|
7945 | | -{ |
---|
7946 | | - unsigned long val; |
---|
7947 | | - |
---|
7948 | | - if (!IS_GEN5(dev_priv)) |
---|
7949 | | - return 0; |
---|
7950 | | - |
---|
7951 | | - spin_lock_irq(&mchdev_lock); |
---|
7952 | | - |
---|
7953 | | - val = __i915_gfx_val(dev_priv); |
---|
7954 | | - |
---|
7955 | | - spin_unlock_irq(&mchdev_lock); |
---|
7956 | | - |
---|
7957 | | - return val; |
---|
7958 | | -} |
---|
7959 | | - |
---|
7960 | | -/** |
---|
7961 | | - * i915_read_mch_val - return value for IPS use |
---|
7962 | | - * |
---|
7963 | | - * Calculate and return a value for the IPS driver to use when deciding whether |
---|
7964 | | - * we have thermal and power headroom to increase CPU or GPU power budget. |
---|
7965 | | - */ |
---|
7966 | | -unsigned long i915_read_mch_val(void) |
---|
7967 | | -{ |
---|
7968 | | - struct drm_i915_private *dev_priv; |
---|
7969 | | - unsigned long chipset_val, graphics_val, ret = 0; |
---|
7970 | | - |
---|
7971 | | - spin_lock_irq(&mchdev_lock); |
---|
7972 | | - if (!i915_mch_dev) |
---|
7973 | | - goto out_unlock; |
---|
7974 | | - dev_priv = i915_mch_dev; |
---|
7975 | | - |
---|
7976 | | - chipset_val = __i915_chipset_val(dev_priv); |
---|
7977 | | - graphics_val = __i915_gfx_val(dev_priv); |
---|
7978 | | - |
---|
7979 | | - ret = chipset_val + graphics_val; |
---|
7980 | | - |
---|
7981 | | -out_unlock: |
---|
7982 | | - spin_unlock_irq(&mchdev_lock); |
---|
7983 | | - |
---|
7984 | | - return ret; |
---|
7985 | | -} |
---|
7986 | | -EXPORT_SYMBOL_GPL(i915_read_mch_val); |
---|
7987 | | - |
---|
7988 | | -/** |
---|
7989 | | - * i915_gpu_raise - raise GPU frequency limit |
---|
7990 | | - * |
---|
7991 | | - * Raise the limit; IPS indicates we have thermal headroom. |
---|
7992 | | - */ |
---|
7993 | | -bool i915_gpu_raise(void) |
---|
7994 | | -{ |
---|
7995 | | - struct drm_i915_private *dev_priv; |
---|
7996 | | - bool ret = true; |
---|
7997 | | - |
---|
7998 | | - spin_lock_irq(&mchdev_lock); |
---|
7999 | | - if (!i915_mch_dev) { |
---|
8000 | | - ret = false; |
---|
8001 | | - goto out_unlock; |
---|
8002 | | - } |
---|
8003 | | - dev_priv = i915_mch_dev; |
---|
8004 | | - |
---|
8005 | | - if (dev_priv->ips.max_delay > dev_priv->ips.fmax) |
---|
8006 | | - dev_priv->ips.max_delay--; |
---|
8007 | | - |
---|
8008 | | -out_unlock: |
---|
8009 | | - spin_unlock_irq(&mchdev_lock); |
---|
8010 | | - |
---|
8011 | | - return ret; |
---|
8012 | | -} |
---|
8013 | | -EXPORT_SYMBOL_GPL(i915_gpu_raise); |
---|
8014 | | - |
---|
8015 | | -/** |
---|
8016 | | - * i915_gpu_lower - lower GPU frequency limit |
---|
8017 | | - * |
---|
8018 | | - * IPS indicates we're close to a thermal limit, so throttle back the GPU |
---|
8019 | | - * frequency maximum. |
---|
8020 | | - */ |
---|
8021 | | -bool i915_gpu_lower(void) |
---|
8022 | | -{ |
---|
8023 | | - struct drm_i915_private *dev_priv; |
---|
8024 | | - bool ret = true; |
---|
8025 | | - |
---|
8026 | | - spin_lock_irq(&mchdev_lock); |
---|
8027 | | - if (!i915_mch_dev) { |
---|
8028 | | - ret = false; |
---|
8029 | | - goto out_unlock; |
---|
8030 | | - } |
---|
8031 | | - dev_priv = i915_mch_dev; |
---|
8032 | | - |
---|
8033 | | - if (dev_priv->ips.max_delay < dev_priv->ips.min_delay) |
---|
8034 | | - dev_priv->ips.max_delay++; |
---|
8035 | | - |
---|
8036 | | -out_unlock: |
---|
8037 | | - spin_unlock_irq(&mchdev_lock); |
---|
8038 | | - |
---|
8039 | | - return ret; |
---|
8040 | | -} |
---|
8041 | | -EXPORT_SYMBOL_GPL(i915_gpu_lower); |
---|
8042 | | - |
---|
8043 | | -/** |
---|
8044 | | - * i915_gpu_busy - indicate GPU business to IPS |
---|
8045 | | - * |
---|
8046 | | - * Tell the IPS driver whether or not the GPU is busy. |
---|
8047 | | - */ |
---|
8048 | | -bool i915_gpu_busy(void) |
---|
8049 | | -{ |
---|
8050 | | - bool ret = false; |
---|
8051 | | - |
---|
8052 | | - spin_lock_irq(&mchdev_lock); |
---|
8053 | | - if (i915_mch_dev) |
---|
8054 | | - ret = i915_mch_dev->gt.awake; |
---|
8055 | | - spin_unlock_irq(&mchdev_lock); |
---|
8056 | | - |
---|
8057 | | - return ret; |
---|
8058 | | -} |
---|
8059 | | -EXPORT_SYMBOL_GPL(i915_gpu_busy); |
---|
8060 | | - |
---|
8061 | | -/** |
---|
8062 | | - * i915_gpu_turbo_disable - disable graphics turbo |
---|
8063 | | - * |
---|
8064 | | - * Disable graphics turbo by resetting the max frequency and setting the |
---|
8065 | | - * current frequency to the default. |
---|
8066 | | - */ |
---|
8067 | | -bool i915_gpu_turbo_disable(void) |
---|
8068 | | -{ |
---|
8069 | | - struct drm_i915_private *dev_priv; |
---|
8070 | | - bool ret = true; |
---|
8071 | | - |
---|
8072 | | - spin_lock_irq(&mchdev_lock); |
---|
8073 | | - if (!i915_mch_dev) { |
---|
8074 | | - ret = false; |
---|
8075 | | - goto out_unlock; |
---|
8076 | | - } |
---|
8077 | | - dev_priv = i915_mch_dev; |
---|
8078 | | - |
---|
8079 | | - dev_priv->ips.max_delay = dev_priv->ips.fstart; |
---|
8080 | | - |
---|
8081 | | - if (!ironlake_set_drps(dev_priv, dev_priv->ips.fstart)) |
---|
8082 | | - ret = false; |
---|
8083 | | - |
---|
8084 | | -out_unlock: |
---|
8085 | | - spin_unlock_irq(&mchdev_lock); |
---|
8086 | | - |
---|
8087 | | - return ret; |
---|
8088 | | -} |
---|
8089 | | -EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); |
---|
8090 | | - |
---|
8091 | | -/** |
---|
8092 | | - * Tells the intel_ips driver that the i915 driver is now loaded, if |
---|
8093 | | - * IPS got loaded first. |
---|
8094 | | - * |
---|
8095 | | - * This awkward dance is so that neither module has to depend on the |
---|
8096 | | - * other in order for IPS to do the appropriate communication of |
---|
8097 | | - * GPU turbo limits to i915. |
---|
8098 | | - */ |
---|
8099 | | -static void |
---|
8100 | | -ips_ping_for_i915_load(void) |
---|
8101 | | -{ |
---|
8102 | | - void (*link)(void); |
---|
8103 | | - |
---|
8104 | | - link = symbol_get(ips_link_to_i915_driver); |
---|
8105 | | - if (link) { |
---|
8106 | | - link(); |
---|
8107 | | - symbol_put(ips_link_to_i915_driver); |
---|
8108 | | - } |
---|
8109 | | -} |
---|
8110 | | - |
---|
8111 | | -void intel_gpu_ips_init(struct drm_i915_private *dev_priv) |
---|
8112 | | -{ |
---|
8113 | | - /* We only register the i915 ips part with intel-ips once everything is |
---|
8114 | | - * set up, to avoid intel-ips sneaking in and reading bogus values. */ |
---|
8115 | | - spin_lock_irq(&mchdev_lock); |
---|
8116 | | - i915_mch_dev = dev_priv; |
---|
8117 | | - spin_unlock_irq(&mchdev_lock); |
---|
8118 | | - |
---|
8119 | | - ips_ping_for_i915_load(); |
---|
8120 | | -} |
---|
8121 | | - |
---|
8122 | | -void intel_gpu_ips_teardown(void) |
---|
8123 | | -{ |
---|
8124 | | - spin_lock_irq(&mchdev_lock); |
---|
8125 | | - i915_mch_dev = NULL; |
---|
8126 | | - spin_unlock_irq(&mchdev_lock); |
---|
8127 | | -} |
---|
8128 | | - |
---|
8129 | | -static void intel_init_emon(struct drm_i915_private *dev_priv) |
---|
8130 | | -{ |
---|
8131 | | - u32 lcfuse; |
---|
8132 | | - u8 pxw[16]; |
---|
8133 | | - int i; |
---|
8134 | | - |
---|
8135 | | - /* Disable to program */ |
---|
8136 | | - I915_WRITE(ECR, 0); |
---|
8137 | | - POSTING_READ(ECR); |
---|
8138 | | - |
---|
8139 | | - /* Program energy weights for various events */ |
---|
8140 | | - I915_WRITE(SDEW, 0x15040d00); |
---|
8141 | | - I915_WRITE(CSIEW0, 0x007f0000); |
---|
8142 | | - I915_WRITE(CSIEW1, 0x1e220004); |
---|
8143 | | - I915_WRITE(CSIEW2, 0x04000004); |
---|
8144 | | - |
---|
8145 | | - for (i = 0; i < 5; i++) |
---|
8146 | | - I915_WRITE(PEW(i), 0); |
---|
8147 | | - for (i = 0; i < 3; i++) |
---|
8148 | | - I915_WRITE(DEW(i), 0); |
---|
8149 | | - |
---|
8150 | | - /* Program P-state weights to account for frequency power adjustment */ |
---|
8151 | | - for (i = 0; i < 16; i++) { |
---|
8152 | | - u32 pxvidfreq = I915_READ(PXVFREQ(i)); |
---|
8153 | | - unsigned long freq = intel_pxfreq(pxvidfreq); |
---|
8154 | | - unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >> |
---|
8155 | | - PXVFREQ_PX_SHIFT; |
---|
8156 | | - unsigned long val; |
---|
8157 | | - |
---|
8158 | | - val = vid * vid; |
---|
8159 | | - val *= (freq / 1000); |
---|
8160 | | - val *= 255; |
---|
8161 | | - val /= (127*127*900); |
---|
8162 | | - if (val > 0xff) |
---|
8163 | | - DRM_ERROR("bad pxval: %ld\n", val); |
---|
8164 | | - pxw[i] = val; |
---|
8165 | | - } |
---|
8166 | | - /* Render standby states get 0 weight */ |
---|
8167 | | - pxw[14] = 0; |
---|
8168 | | - pxw[15] = 0; |
---|
8169 | | - |
---|
8170 | | - for (i = 0; i < 4; i++) { |
---|
8171 | | - u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) | |
---|
8172 | | - (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]); |
---|
8173 | | - I915_WRITE(PXW(i), val); |
---|
8174 | | - } |
---|
8175 | | - |
---|
8176 | | - /* Adjust magic regs to magic values (more experimental results) */ |
---|
8177 | | - I915_WRITE(OGW0, 0); |
---|
8178 | | - I915_WRITE(OGW1, 0); |
---|
8179 | | - I915_WRITE(EG0, 0x00007f00); |
---|
8180 | | - I915_WRITE(EG1, 0x0000000e); |
---|
8181 | | - I915_WRITE(EG2, 0x000e0000); |
---|
8182 | | - I915_WRITE(EG3, 0x68000300); |
---|
8183 | | - I915_WRITE(EG4, 0x42000000); |
---|
8184 | | - I915_WRITE(EG5, 0x00140031); |
---|
8185 | | - I915_WRITE(EG6, 0); |
---|
8186 | | - I915_WRITE(EG7, 0); |
---|
8187 | | - |
---|
8188 | | - for (i = 0; i < 8; i++) |
---|
8189 | | - I915_WRITE(PXWL(i), 0); |
---|
8190 | | - |
---|
8191 | | - /* Enable PMON + select events */ |
---|
8192 | | - I915_WRITE(ECR, 0x80000019); |
---|
8193 | | - |
---|
8194 | | - lcfuse = I915_READ(LCFUSE02); |
---|
8195 | | - |
---|
8196 | | - dev_priv->ips.corr = (lcfuse & LCFUSE_HIV_MASK); |
---|
8197 | | -} |
---|
8198 | | - |
---|
8199 | | -static bool i915_rc6_ctx_corrupted(struct drm_i915_private *dev_priv) |
---|
8200 | | -{ |
---|
8201 | | - return !I915_READ(GEN8_RC6_CTX_INFO); |
---|
8202 | | -} |
---|
8203 | | - |
---|
8204 | | -static void i915_rc6_ctx_wa_init(struct drm_i915_private *i915) |
---|
8205 | | -{ |
---|
8206 | | - if (!NEEDS_RC6_CTX_CORRUPTION_WA(i915)) |
---|
8207 | | - return; |
---|
8208 | | - |
---|
8209 | | - if (i915_rc6_ctx_corrupted(i915)) { |
---|
8210 | | - DRM_INFO("RC6 context corrupted, disabling runtime power management\n"); |
---|
8211 | | - i915->gt_pm.rc6.ctx_corrupted = true; |
---|
8212 | | - intel_runtime_pm_get(i915); |
---|
8213 | | - } |
---|
8214 | | -} |
---|
8215 | | - |
---|
8216 | | -static void i915_rc6_ctx_wa_cleanup(struct drm_i915_private *i915) |
---|
8217 | | -{ |
---|
8218 | | - if (i915->gt_pm.rc6.ctx_corrupted) { |
---|
8219 | | - intel_runtime_pm_put(i915); |
---|
8220 | | - i915->gt_pm.rc6.ctx_corrupted = false; |
---|
8221 | | - } |
---|
8222 | | -} |
---|
8223 | | - |
---|
8224 | | -/** |
---|
8225 | | - * i915_rc6_ctx_wa_suspend - system suspend sequence for the RC6 CTX WA |
---|
8226 | | - * @i915: i915 device |
---|
8227 | | - * |
---|
8228 | | - * Perform any steps needed to clean up the RC6 CTX WA before system suspend. |
---|
8229 | | - */ |
---|
8230 | | -void i915_rc6_ctx_wa_suspend(struct drm_i915_private *i915) |
---|
8231 | | -{ |
---|
8232 | | - if (i915->gt_pm.rc6.ctx_corrupted) |
---|
8233 | | - intel_runtime_pm_put(i915); |
---|
8234 | | -} |
---|
8235 | | - |
---|
8236 | | -/** |
---|
8237 | | - * i915_rc6_ctx_wa_resume - system resume sequence for the RC6 CTX WA |
---|
8238 | | - * @i915: i915 device |
---|
8239 | | - * |
---|
8240 | | - * Perform any steps needed to re-init the RC6 CTX WA after system resume. |
---|
8241 | | - */ |
---|
8242 | | -void i915_rc6_ctx_wa_resume(struct drm_i915_private *i915) |
---|
8243 | | -{ |
---|
8244 | | - if (!i915->gt_pm.rc6.ctx_corrupted) |
---|
8245 | | - return; |
---|
8246 | | - |
---|
8247 | | - if (i915_rc6_ctx_corrupted(i915)) { |
---|
8248 | | - intel_runtime_pm_get(i915); |
---|
8249 | | - return; |
---|
8250 | | - } |
---|
8251 | | - |
---|
8252 | | - DRM_INFO("RC6 context restored, re-enabling runtime power management\n"); |
---|
8253 | | - i915->gt_pm.rc6.ctx_corrupted = false; |
---|
8254 | | -} |
---|
8255 | | - |
---|
8256 | | -static void intel_disable_rc6(struct drm_i915_private *dev_priv); |
---|
8257 | | - |
---|
8258 | | -/** |
---|
8259 | | - * i915_rc6_ctx_wa_check - check for a new RC6 CTX corruption |
---|
8260 | | - * @i915: i915 device |
---|
8261 | | - * |
---|
8262 | | - * Check if an RC6 CTX corruption has happened since the last check and if so |
---|
8263 | | - * disable RC6 and runtime power management. |
---|
8264 | | - * |
---|
8265 | | - * Return false if no context corruption has happened since the last call of |
---|
8266 | | - * this function, true otherwise. |
---|
8267 | | -*/ |
---|
8268 | | -bool i915_rc6_ctx_wa_check(struct drm_i915_private *i915) |
---|
8269 | | -{ |
---|
8270 | | - if (!NEEDS_RC6_CTX_CORRUPTION_WA(i915)) |
---|
8271 | | - return false; |
---|
8272 | | - |
---|
8273 | | - if (i915->gt_pm.rc6.ctx_corrupted) |
---|
8274 | | - return false; |
---|
8275 | | - |
---|
8276 | | - if (!i915_rc6_ctx_corrupted(i915)) |
---|
8277 | | - return false; |
---|
8278 | | - |
---|
8279 | | - DRM_NOTE("RC6 context corruption, disabling runtime power management\n"); |
---|
8280 | | - |
---|
8281 | | - intel_disable_rc6(i915); |
---|
8282 | | - i915->gt_pm.rc6.ctx_corrupted = true; |
---|
8283 | | - intel_runtime_pm_get_noresume(i915); |
---|
8284 | | - |
---|
8285 | | - return true; |
---|
8286 | | -} |
---|
8287 | | - |
---|
8288 | | -void intel_init_gt_powersave(struct drm_i915_private *dev_priv) |
---|
8289 | | -{ |
---|
8290 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
8291 | | - |
---|
8292 | | - /* |
---|
8293 | | - * RPM depends on RC6 to save restore the GT HW context, so make RC6 a |
---|
8294 | | - * requirement. |
---|
8295 | | - */ |
---|
8296 | | - if (!sanitize_rc6(dev_priv)) { |
---|
8297 | | - DRM_INFO("RC6 disabled, disabling runtime PM support\n"); |
---|
8298 | | - intel_runtime_pm_get(dev_priv); |
---|
8299 | | - } |
---|
8300 | | - |
---|
8301 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
8302 | | - |
---|
8303 | | - i915_rc6_ctx_wa_init(dev_priv); |
---|
8304 | | - |
---|
8305 | | - /* Initialize RPS limits (for userspace) */ |
---|
8306 | | - if (IS_CHERRYVIEW(dev_priv)) |
---|
8307 | | - cherryview_init_gt_powersave(dev_priv); |
---|
8308 | | - else if (IS_VALLEYVIEW(dev_priv)) |
---|
8309 | | - valleyview_init_gt_powersave(dev_priv); |
---|
8310 | | - else if (INTEL_GEN(dev_priv) >= 6) |
---|
8311 | | - gen6_init_rps_frequencies(dev_priv); |
---|
8312 | | - |
---|
8313 | | - /* Derive initial user preferences/limits from the hardware limits */ |
---|
8314 | | - rps->idle_freq = rps->min_freq; |
---|
8315 | | - rps->cur_freq = rps->idle_freq; |
---|
8316 | | - |
---|
8317 | | - rps->max_freq_softlimit = rps->max_freq; |
---|
8318 | | - rps->min_freq_softlimit = rps->min_freq; |
---|
8319 | | - |
---|
8320 | | - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) |
---|
8321 | | - rps->min_freq_softlimit = |
---|
8322 | | - max_t(int, |
---|
8323 | | - rps->efficient_freq, |
---|
8324 | | - intel_freq_opcode(dev_priv, 450)); |
---|
8325 | | - |
---|
8326 | | - /* After setting max-softlimit, find the overclock max freq */ |
---|
8327 | | - if (IS_GEN6(dev_priv) || |
---|
8328 | | - IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) { |
---|
8329 | | - u32 params = 0; |
---|
8330 | | - |
---|
8331 | | - sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS, ¶ms); |
---|
8332 | | - if (params & BIT(31)) { /* OC supported */ |
---|
8333 | | - DRM_DEBUG_DRIVER("Overclocking supported, max: %dMHz, overclock: %dMHz\n", |
---|
8334 | | - (rps->max_freq & 0xff) * 50, |
---|
8335 | | - (params & 0xff) * 50); |
---|
8336 | | - rps->max_freq = params & 0xff; |
---|
8337 | | - } |
---|
8338 | | - } |
---|
8339 | | - |
---|
8340 | | - /* Finally allow us to boost to max by default */ |
---|
8341 | | - rps->boost_freq = rps->max_freq; |
---|
8342 | | - |
---|
8343 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
8344 | | -} |
---|
8345 | | - |
---|
8346 | | -void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv) |
---|
8347 | | -{ |
---|
8348 | | - if (IS_VALLEYVIEW(dev_priv)) |
---|
8349 | | - valleyview_cleanup_gt_powersave(dev_priv); |
---|
8350 | | - |
---|
8351 | | - i915_rc6_ctx_wa_cleanup(dev_priv); |
---|
8352 | | - |
---|
8353 | | - if (!HAS_RC6(dev_priv)) |
---|
8354 | | - intel_runtime_pm_put(dev_priv); |
---|
8355 | | -} |
---|
8356 | | - |
---|
8357 | | -/** |
---|
8358 | | - * intel_suspend_gt_powersave - suspend PM work and helper threads |
---|
8359 | | - * @dev_priv: i915 device |
---|
8360 | | - * |
---|
8361 | | - * We don't want to disable RC6 or other features here, we just want |
---|
8362 | | - * to make sure any work we've queued has finished and won't bother |
---|
8363 | | - * us while we're suspended. |
---|
8364 | | - */ |
---|
8365 | | -void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv) |
---|
8366 | | -{ |
---|
8367 | | - if (INTEL_GEN(dev_priv) < 6) |
---|
8368 | | - return; |
---|
8369 | | - |
---|
8370 | | - /* gen6_rps_idle() will be called later to disable interrupts */ |
---|
8371 | | -} |
---|
8372 | | - |
---|
8373 | | -void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) |
---|
8374 | | -{ |
---|
8375 | | - dev_priv->gt_pm.rps.enabled = true; /* force RPS disabling */ |
---|
8376 | | - dev_priv->gt_pm.rc6.enabled = true; /* force RC6 disabling */ |
---|
8377 | | - intel_disable_gt_powersave(dev_priv); |
---|
8378 | | - |
---|
8379 | | - if (INTEL_GEN(dev_priv) >= 11) |
---|
8380 | | - gen11_reset_rps_interrupts(dev_priv); |
---|
8381 | | - else |
---|
8382 | | - gen6_reset_rps_interrupts(dev_priv); |
---|
8383 | | -} |
---|
8384 | | - |
---|
8385 | | -static inline void intel_disable_llc_pstate(struct drm_i915_private *i915) |
---|
8386 | | -{ |
---|
8387 | | - lockdep_assert_held(&i915->pcu_lock); |
---|
8388 | | - |
---|
8389 | | - if (!i915->gt_pm.llc_pstate.enabled) |
---|
8390 | | - return; |
---|
8391 | | - |
---|
8392 | | - /* Currently there is no HW configuration to be done to disable. */ |
---|
8393 | | - |
---|
8394 | | - i915->gt_pm.llc_pstate.enabled = false; |
---|
8395 | | -} |
---|
8396 | | - |
---|
8397 | | -static void __intel_disable_rc6(struct drm_i915_private *dev_priv) |
---|
8398 | | -{ |
---|
8399 | | - lockdep_assert_held(&dev_priv->pcu_lock); |
---|
8400 | | - |
---|
8401 | | - if (!dev_priv->gt_pm.rc6.enabled) |
---|
8402 | | - return; |
---|
8403 | | - |
---|
8404 | | - if (INTEL_GEN(dev_priv) >= 9) |
---|
8405 | | - gen9_disable_rc6(dev_priv); |
---|
8406 | | - else if (IS_CHERRYVIEW(dev_priv)) |
---|
8407 | | - cherryview_disable_rc6(dev_priv); |
---|
8408 | | - else if (IS_VALLEYVIEW(dev_priv)) |
---|
8409 | | - valleyview_disable_rc6(dev_priv); |
---|
8410 | | - else if (INTEL_GEN(dev_priv) >= 6) |
---|
8411 | | - gen6_disable_rc6(dev_priv); |
---|
8412 | | - |
---|
8413 | | - dev_priv->gt_pm.rc6.enabled = false; |
---|
8414 | | -} |
---|
8415 | | - |
---|
8416 | | -static void intel_disable_rc6(struct drm_i915_private *dev_priv) |
---|
8417 | | -{ |
---|
8418 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
8419 | | - __intel_disable_rc6(dev_priv); |
---|
8420 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
8421 | | -} |
---|
8422 | | - |
---|
8423 | | -static void intel_disable_rps(struct drm_i915_private *dev_priv) |
---|
8424 | | -{ |
---|
8425 | | - lockdep_assert_held(&dev_priv->pcu_lock); |
---|
8426 | | - |
---|
8427 | | - if (!dev_priv->gt_pm.rps.enabled) |
---|
8428 | | - return; |
---|
8429 | | - |
---|
8430 | | - if (INTEL_GEN(dev_priv) >= 9) |
---|
8431 | | - gen9_disable_rps(dev_priv); |
---|
8432 | | - else if (IS_CHERRYVIEW(dev_priv)) |
---|
8433 | | - cherryview_disable_rps(dev_priv); |
---|
8434 | | - else if (IS_VALLEYVIEW(dev_priv)) |
---|
8435 | | - valleyview_disable_rps(dev_priv); |
---|
8436 | | - else if (INTEL_GEN(dev_priv) >= 6) |
---|
8437 | | - gen6_disable_rps(dev_priv); |
---|
8438 | | - else if (IS_IRONLAKE_M(dev_priv)) |
---|
8439 | | - ironlake_disable_drps(dev_priv); |
---|
8440 | | - |
---|
8441 | | - dev_priv->gt_pm.rps.enabled = false; |
---|
8442 | | -} |
---|
8443 | | - |
---|
8444 | | -void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) |
---|
8445 | | -{ |
---|
8446 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
8447 | | - |
---|
8448 | | - __intel_disable_rc6(dev_priv); |
---|
8449 | | - intel_disable_rps(dev_priv); |
---|
8450 | | - if (HAS_LLC(dev_priv)) |
---|
8451 | | - intel_disable_llc_pstate(dev_priv); |
---|
8452 | | - |
---|
8453 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
8454 | | -} |
---|
8455 | | - |
---|
8456 | | -static inline void intel_enable_llc_pstate(struct drm_i915_private *i915) |
---|
8457 | | -{ |
---|
8458 | | - lockdep_assert_held(&i915->pcu_lock); |
---|
8459 | | - |
---|
8460 | | - if (i915->gt_pm.llc_pstate.enabled) |
---|
8461 | | - return; |
---|
8462 | | - |
---|
8463 | | - gen6_update_ring_freq(i915); |
---|
8464 | | - |
---|
8465 | | - i915->gt_pm.llc_pstate.enabled = true; |
---|
8466 | | -} |
---|
8467 | | - |
---|
8468 | | -static void intel_enable_rc6(struct drm_i915_private *dev_priv) |
---|
8469 | | -{ |
---|
8470 | | - lockdep_assert_held(&dev_priv->pcu_lock); |
---|
8471 | | - |
---|
8472 | | - if (dev_priv->gt_pm.rc6.enabled) |
---|
8473 | | - return; |
---|
8474 | | - |
---|
8475 | | - if (dev_priv->gt_pm.rc6.ctx_corrupted) |
---|
8476 | | - return; |
---|
8477 | | - |
---|
8478 | | - if (IS_CHERRYVIEW(dev_priv)) |
---|
8479 | | - cherryview_enable_rc6(dev_priv); |
---|
8480 | | - else if (IS_VALLEYVIEW(dev_priv)) |
---|
8481 | | - valleyview_enable_rc6(dev_priv); |
---|
8482 | | - else if (INTEL_GEN(dev_priv) >= 9) |
---|
8483 | | - gen9_enable_rc6(dev_priv); |
---|
8484 | | - else if (IS_BROADWELL(dev_priv)) |
---|
8485 | | - gen8_enable_rc6(dev_priv); |
---|
8486 | | - else if (INTEL_GEN(dev_priv) >= 6) |
---|
8487 | | - gen6_enable_rc6(dev_priv); |
---|
8488 | | - |
---|
8489 | | - dev_priv->gt_pm.rc6.enabled = true; |
---|
8490 | | -} |
---|
8491 | | - |
---|
8492 | | -static void intel_enable_rps(struct drm_i915_private *dev_priv) |
---|
8493 | | -{ |
---|
8494 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
8495 | | - |
---|
8496 | | - lockdep_assert_held(&dev_priv->pcu_lock); |
---|
8497 | | - |
---|
8498 | | - if (rps->enabled) |
---|
8499 | | - return; |
---|
8500 | | - |
---|
8501 | | - if (IS_CHERRYVIEW(dev_priv)) { |
---|
8502 | | - cherryview_enable_rps(dev_priv); |
---|
8503 | | - } else if (IS_VALLEYVIEW(dev_priv)) { |
---|
8504 | | - valleyview_enable_rps(dev_priv); |
---|
8505 | | - } else if (INTEL_GEN(dev_priv) >= 9) { |
---|
8506 | | - gen9_enable_rps(dev_priv); |
---|
8507 | | - } else if (IS_BROADWELL(dev_priv)) { |
---|
8508 | | - gen8_enable_rps(dev_priv); |
---|
8509 | | - } else if (INTEL_GEN(dev_priv) >= 6) { |
---|
8510 | | - gen6_enable_rps(dev_priv); |
---|
8511 | | - } else if (IS_IRONLAKE_M(dev_priv)) { |
---|
8512 | | - ironlake_enable_drps(dev_priv); |
---|
8513 | | - intel_init_emon(dev_priv); |
---|
8514 | | - } |
---|
8515 | | - |
---|
8516 | | - WARN_ON(rps->max_freq < rps->min_freq); |
---|
8517 | | - WARN_ON(rps->idle_freq > rps->max_freq); |
---|
8518 | | - |
---|
8519 | | - WARN_ON(rps->efficient_freq < rps->min_freq); |
---|
8520 | | - WARN_ON(rps->efficient_freq > rps->max_freq); |
---|
8521 | | - |
---|
8522 | | - rps->enabled = true; |
---|
8523 | | -} |
---|
8524 | | - |
---|
8525 | | -void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) |
---|
8526 | | -{ |
---|
8527 | | - /* Powersaving is controlled by the host when inside a VM */ |
---|
8528 | | - if (intel_vgpu_active(dev_priv)) |
---|
8529 | | - return; |
---|
8530 | | - |
---|
8531 | | - mutex_lock(&dev_priv->pcu_lock); |
---|
8532 | | - |
---|
8533 | | - if (HAS_RC6(dev_priv)) |
---|
8534 | | - intel_enable_rc6(dev_priv); |
---|
8535 | | - intel_enable_rps(dev_priv); |
---|
8536 | | - if (HAS_LLC(dev_priv)) |
---|
8537 | | - intel_enable_llc_pstate(dev_priv); |
---|
8538 | | - |
---|
8539 | | - mutex_unlock(&dev_priv->pcu_lock); |
---|
8540 | 6861 | } |
---|
8541 | 6862 | |
---|
8542 | 6863 | static void ibx_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
.. | .. |
---|
8565 | 6886 | |
---|
8566 | 6887 | static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
8567 | 6888 | { |
---|
8568 | | - uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; |
---|
| 6889 | + u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; |
---|
8569 | 6890 | |
---|
8570 | 6891 | /* |
---|
8571 | 6892 | * Required for FBC |
---|
.. | .. |
---|
8618 | 6939 | I915_WRITE(ILK_DISPLAY_CHICKEN2, |
---|
8619 | 6940 | I915_READ(ILK_DISPLAY_CHICKEN2) | |
---|
8620 | 6941 | ILK_ELPIN_409_SELECT); |
---|
8621 | | - I915_WRITE(_3D_CHICKEN2, |
---|
8622 | | - _3D_CHICKEN2_WM_READ_PIPELINED << 16 | |
---|
8623 | | - _3D_CHICKEN2_WM_READ_PIPELINED); |
---|
8624 | | - |
---|
8625 | | - /* WaDisableRenderCachePipelinedFlush:ilk */ |
---|
8626 | | - I915_WRITE(CACHE_MODE_0, |
---|
8627 | | - _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE)); |
---|
8628 | | - |
---|
8629 | | - /* WaDisable_RenderCache_OperationalFlush:ilk */ |
---|
8630 | | - I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
---|
8631 | 6942 | |
---|
8632 | 6943 | g4x_disable_trickle_feed(dev_priv); |
---|
8633 | 6944 | |
---|
.. | .. |
---|
8636 | 6947 | |
---|
8637 | 6948 | static void cpt_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
8638 | 6949 | { |
---|
8639 | | - int pipe; |
---|
8640 | | - uint32_t val; |
---|
| 6950 | + enum pipe pipe; |
---|
| 6951 | + u32 val; |
---|
8641 | 6952 | |
---|
8642 | 6953 | /* |
---|
8643 | 6954 | * On Ibex Peak and Cougar Point, we need to disable clock |
---|
.. | .. |
---|
8658 | 6969 | val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED; |
---|
8659 | 6970 | if (dev_priv->vbt.fdi_rx_polarity_inverted) |
---|
8660 | 6971 | val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED; |
---|
8661 | | - val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK; |
---|
8662 | 6972 | val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER; |
---|
8663 | 6973 | val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH; |
---|
8664 | 6974 | I915_WRITE(TRANS_CHICKEN2(pipe), val); |
---|
.. | .. |
---|
8672 | 6982 | |
---|
8673 | 6983 | static void gen6_check_mch_setup(struct drm_i915_private *dev_priv) |
---|
8674 | 6984 | { |
---|
8675 | | - uint32_t tmp; |
---|
| 6985 | + u32 tmp; |
---|
8676 | 6986 | |
---|
8677 | 6987 | tmp = I915_READ(MCH_SSKPD); |
---|
8678 | 6988 | if ((tmp & MCH_SSKPD_WM0_MASK) != MCH_SSKPD_WM0_VAL) |
---|
8679 | | - DRM_DEBUG_KMS("Wrong MCH_SSKPD value: 0x%08x This can cause underruns.\n", |
---|
8680 | | - tmp); |
---|
| 6989 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 6990 | + "Wrong MCH_SSKPD value: 0x%08x This can cause underruns.\n", |
---|
| 6991 | + tmp); |
---|
8681 | 6992 | } |
---|
8682 | 6993 | |
---|
8683 | 6994 | static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
8684 | 6995 | { |
---|
8685 | | - uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; |
---|
| 6996 | + u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; |
---|
8686 | 6997 | |
---|
8687 | 6998 | I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate); |
---|
8688 | 6999 | |
---|
8689 | 7000 | I915_WRITE(ILK_DISPLAY_CHICKEN2, |
---|
8690 | 7001 | I915_READ(ILK_DISPLAY_CHICKEN2) | |
---|
8691 | 7002 | ILK_ELPIN_409_SELECT); |
---|
8692 | | - |
---|
8693 | | - /* WaDisableHiZPlanesWhenMSAAEnabled:snb */ |
---|
8694 | | - I915_WRITE(_3D_CHICKEN, |
---|
8695 | | - _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB)); |
---|
8696 | | - |
---|
8697 | | - /* WaDisable_RenderCache_OperationalFlush:snb */ |
---|
8698 | | - I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
---|
8699 | | - |
---|
8700 | | - /* |
---|
8701 | | - * BSpec recoomends 8x4 when MSAA is used, |
---|
8702 | | - * however in practice 16x4 seems fastest. |
---|
8703 | | - * |
---|
8704 | | - * Note that PS/WM thread counts depend on the WIZ hashing |
---|
8705 | | - * disable bit, which we don't touch here, but it's good |
---|
8706 | | - * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). |
---|
8707 | | - */ |
---|
8708 | | - I915_WRITE(GEN6_GT_MODE, |
---|
8709 | | - _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); |
---|
8710 | | - |
---|
8711 | | - I915_WRITE(CACHE_MODE_0, |
---|
8712 | | - _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB)); |
---|
8713 | 7003 | |
---|
8714 | 7004 | I915_WRITE(GEN6_UCGCTL1, |
---|
8715 | 7005 | I915_READ(GEN6_UCGCTL1) | |
---|
.. | .. |
---|
8732 | 7022 | I915_WRITE(GEN6_UCGCTL2, |
---|
8733 | 7023 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | |
---|
8734 | 7024 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); |
---|
8735 | | - |
---|
8736 | | - /* WaStripsFansDisableFastClipPerformanceFix:snb */ |
---|
8737 | | - I915_WRITE(_3D_CHICKEN3, |
---|
8738 | | - _MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL)); |
---|
8739 | | - |
---|
8740 | | - /* |
---|
8741 | | - * Bspec says: |
---|
8742 | | - * "This bit must be set if 3DSTATE_CLIP clip mode is set to normal and |
---|
8743 | | - * 3DSTATE_SF number of SF output attributes is more than 16." |
---|
8744 | | - */ |
---|
8745 | | - I915_WRITE(_3D_CHICKEN3, |
---|
8746 | | - _MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH)); |
---|
8747 | 7025 | |
---|
8748 | 7026 | /* |
---|
8749 | 7027 | * According to the spec the following bits should be |
---|
.. | .. |
---|
8774 | 7052 | gen6_check_mch_setup(dev_priv); |
---|
8775 | 7053 | } |
---|
8776 | 7054 | |
---|
8777 | | -static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) |
---|
8778 | | -{ |
---|
8779 | | - uint32_t reg = I915_READ(GEN7_FF_THREAD_MODE); |
---|
8780 | | - |
---|
8781 | | - /* |
---|
8782 | | - * WaVSThreadDispatchOverride:ivb,vlv |
---|
8783 | | - * |
---|
8784 | | - * This actually overrides the dispatch |
---|
8785 | | - * mode for all thread types. |
---|
8786 | | - */ |
---|
8787 | | - reg &= ~GEN7_FF_SCHED_MASK; |
---|
8788 | | - reg |= GEN7_FF_TS_SCHED_HW; |
---|
8789 | | - reg |= GEN7_FF_VS_SCHED_HW; |
---|
8790 | | - reg |= GEN7_FF_DS_SCHED_HW; |
---|
8791 | | - |
---|
8792 | | - I915_WRITE(GEN7_FF_THREAD_MODE, reg); |
---|
8793 | | -} |
---|
8794 | | - |
---|
8795 | 7055 | static void lpt_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
8796 | 7056 | { |
---|
8797 | 7057 | /* |
---|
.. | .. |
---|
8812 | 7072 | static void lpt_suspend_hw(struct drm_i915_private *dev_priv) |
---|
8813 | 7073 | { |
---|
8814 | 7074 | if (HAS_PCH_LPT_LP(dev_priv)) { |
---|
8815 | | - uint32_t val = I915_READ(SOUTH_DSPCLK_GATE_D); |
---|
| 7075 | + u32 val = I915_READ(SOUTH_DSPCLK_GATE_D); |
---|
8816 | 7076 | |
---|
8817 | 7077 | val &= ~PCH_LP_PARTITION_LEVEL_DISABLE; |
---|
8818 | 7078 | I915_WRITE(SOUTH_DSPCLK_GATE_D, val); |
---|
.. | .. |
---|
8847 | 7107 | |
---|
8848 | 7108 | static void icl_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
8849 | 7109 | { |
---|
| 7110 | + /* Wa_1409120013:icl,ehl */ |
---|
| 7111 | + I915_WRITE(ILK_DPFC_CHICKEN, |
---|
| 7112 | + ILK_DPFC_CHICKEN_COMP_DUMMY_PIXEL); |
---|
| 7113 | + |
---|
8850 | 7114 | /* This is not an Wa. Enable to reduce Sampler power */ |
---|
8851 | 7115 | I915_WRITE(GEN10_DFR_RATIO_EN_AND_CHICKEN, |
---|
8852 | 7116 | I915_READ(GEN10_DFR_RATIO_EN_AND_CHICKEN) & ~DFR_DISABLE); |
---|
| 7117 | + |
---|
| 7118 | + /*Wa_14010594013:icl, ehl */ |
---|
| 7119 | + intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, |
---|
| 7120 | + 0, CNL_DELAY_PMRSP); |
---|
| 7121 | +} |
---|
| 7122 | + |
---|
| 7123 | +static void tgl_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
| 7124 | +{ |
---|
| 7125 | + /* Wa_1409120013:tgl */ |
---|
| 7126 | + I915_WRITE(ILK_DPFC_CHICKEN, |
---|
| 7127 | + ILK_DPFC_CHICKEN_COMP_DUMMY_PIXEL); |
---|
| 7128 | + |
---|
| 7129 | + /* Wa_1409825376:tgl (pre-prod)*/ |
---|
| 7130 | + if (IS_TGL_DISP_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_B1)) |
---|
| 7131 | + I915_WRITE(GEN9_CLKGATE_DIS_3, I915_READ(GEN9_CLKGATE_DIS_3) | |
---|
| 7132 | + TGL_VRH_GATING_DIS); |
---|
| 7133 | + |
---|
| 7134 | + /* Wa_14011059788:tgl */ |
---|
| 7135 | + intel_uncore_rmw(&dev_priv->uncore, GEN10_DFR_RATIO_EN_AND_CHICKEN, |
---|
| 7136 | + 0, DFR_DISABLE); |
---|
8853 | 7137 | } |
---|
8854 | 7138 | |
---|
8855 | 7139 | static void cnp_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
.. | .. |
---|
8875 | 7159 | I915_WRITE(GEN8_CHICKEN_DCPR_1, |
---|
8876 | 7160 | I915_READ(GEN8_CHICKEN_DCPR_1) | MASK_WAKEMEM); |
---|
8877 | 7161 | |
---|
8878 | | - /* WaFbcWakeMemOn:cnl */ |
---|
| 7162 | + /* |
---|
| 7163 | + * WaFbcWakeMemOn:cnl |
---|
| 7164 | + * Display WA #0859: cnl |
---|
| 7165 | + */ |
---|
8879 | 7166 | I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | |
---|
8880 | 7167 | DISP_FBC_MEMORY_WAKE); |
---|
8881 | 7168 | |
---|
8882 | 7169 | val = I915_READ(SLICE_UNIT_LEVEL_CLKGATE); |
---|
8883 | 7170 | /* ReadHitWriteOnlyDisable:cnl */ |
---|
8884 | 7171 | val |= RCCUNIT_CLKGATE_DIS; |
---|
8885 | | - /* WaSarbUnitClockGatingDisable:cnl (pre-prod) */ |
---|
8886 | | - if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_B0)) |
---|
8887 | | - val |= SARBUNIT_CLKGATE_DIS; |
---|
8888 | 7172 | I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE, val); |
---|
8889 | 7173 | |
---|
8890 | 7174 | /* Wa_2201832410:cnl */ |
---|
.. | .. |
---|
8904 | 7188 | cnp_init_clock_gating(dev_priv); |
---|
8905 | 7189 | gen9_init_clock_gating(dev_priv); |
---|
8906 | 7190 | |
---|
8907 | | - /* WaFbcNukeOnHostModify:cfl */ |
---|
| 7191 | + /* |
---|
| 7192 | + * WaFbcTurnOffFbcWatermark:cfl |
---|
| 7193 | + * Display WA #0562: cfl |
---|
| 7194 | + */ |
---|
| 7195 | + I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | |
---|
| 7196 | + DISP_FBC_WM_DIS); |
---|
| 7197 | + |
---|
| 7198 | + /* |
---|
| 7199 | + * WaFbcNukeOnHostModify:cfl |
---|
| 7200 | + * Display WA #0873: cfl |
---|
| 7201 | + */ |
---|
8908 | 7202 | I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | |
---|
8909 | 7203 | ILK_DPFC_NUKE_ON_ANY_MODIFICATION); |
---|
8910 | 7204 | } |
---|
.. | .. |
---|
8914 | 7208 | gen9_init_clock_gating(dev_priv); |
---|
8915 | 7209 | |
---|
8916 | 7210 | /* WaDisableSDEUnitClockGating:kbl */ |
---|
8917 | | - if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0)) |
---|
| 7211 | + if (IS_KBL_GT_REVID(dev_priv, 0, KBL_REVID_B0)) |
---|
8918 | 7212 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
---|
8919 | 7213 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); |
---|
8920 | 7214 | |
---|
8921 | 7215 | /* WaDisableGamClockGating:kbl */ |
---|
8922 | | - if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0)) |
---|
| 7216 | + if (IS_KBL_GT_REVID(dev_priv, 0, KBL_REVID_B0)) |
---|
8923 | 7217 | I915_WRITE(GEN6_UCGCTL1, I915_READ(GEN6_UCGCTL1) | |
---|
8924 | 7218 | GEN6_GAMUNIT_CLOCK_GATE_DISABLE); |
---|
8925 | 7219 | |
---|
8926 | | - /* WaFbcNukeOnHostModify:kbl */ |
---|
| 7220 | + /* |
---|
| 7221 | + * WaFbcTurnOffFbcWatermark:kbl |
---|
| 7222 | + * Display WA #0562: kbl |
---|
| 7223 | + */ |
---|
| 7224 | + I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | |
---|
| 7225 | + DISP_FBC_WM_DIS); |
---|
| 7226 | + |
---|
| 7227 | + /* |
---|
| 7228 | + * WaFbcNukeOnHostModify:kbl |
---|
| 7229 | + * Display WA #0873: kbl |
---|
| 7230 | + */ |
---|
8927 | 7231 | I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | |
---|
8928 | 7232 | ILK_DPFC_NUKE_ON_ANY_MODIFICATION); |
---|
8929 | 7233 | } |
---|
.. | .. |
---|
8932 | 7236 | { |
---|
8933 | 7237 | gen9_init_clock_gating(dev_priv); |
---|
8934 | 7238 | |
---|
| 7239 | + /* WaDisableDopClockGating:skl */ |
---|
| 7240 | + I915_WRITE(GEN7_MISCCPCTL, I915_READ(GEN7_MISCCPCTL) & |
---|
| 7241 | + ~GEN7_DOP_CLOCK_GATE_ENABLE); |
---|
| 7242 | + |
---|
8935 | 7243 | /* WAC6entrylatency:skl */ |
---|
8936 | 7244 | I915_WRITE(FBC_LLC_READ_CTRL, I915_READ(FBC_LLC_READ_CTRL) | |
---|
8937 | 7245 | FBC_LLC_FULLY_OPEN); |
---|
8938 | 7246 | |
---|
8939 | | - /* WaFbcNukeOnHostModify:skl */ |
---|
| 7247 | + /* |
---|
| 7248 | + * WaFbcTurnOffFbcWatermark:skl |
---|
| 7249 | + * Display WA #0562: skl |
---|
| 7250 | + */ |
---|
| 7251 | + I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | |
---|
| 7252 | + DISP_FBC_WM_DIS); |
---|
| 7253 | + |
---|
| 7254 | + /* |
---|
| 7255 | + * WaFbcNukeOnHostModify:skl |
---|
| 7256 | + * Display WA #0873: skl |
---|
| 7257 | + */ |
---|
8940 | 7258 | I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | |
---|
8941 | 7259 | ILK_DPFC_NUKE_ON_ANY_MODIFICATION); |
---|
| 7260 | + |
---|
| 7261 | + /* |
---|
| 7262 | + * WaFbcHighMemBwCorruptionAvoidance:skl |
---|
| 7263 | + * Display WA #0883: skl |
---|
| 7264 | + */ |
---|
| 7265 | + I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) | |
---|
| 7266 | + ILK_DPFC_DISABLE_DUMMY0); |
---|
8942 | 7267 | } |
---|
8943 | 7268 | |
---|
8944 | 7269 | static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
8945 | 7270 | { |
---|
8946 | | - /* The GTT cache must be disabled if the system is using 2M pages. */ |
---|
8947 | | - bool can_use_gtt_cache = !HAS_PAGE_SIZES(dev_priv, |
---|
8948 | | - I915_GTT_PAGE_SIZE_2M); |
---|
8949 | 7271 | enum pipe pipe; |
---|
| 7272 | + |
---|
| 7273 | + /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ |
---|
| 7274 | + I915_WRITE(CHICKEN_PIPESL_1(PIPE_A), |
---|
| 7275 | + I915_READ(CHICKEN_PIPESL_1(PIPE_A)) | |
---|
| 7276 | + HSW_FBCQ_DIS); |
---|
8950 | 7277 | |
---|
8951 | 7278 | /* WaSwitchSolVfFArbitrationPriority:bdw */ |
---|
8952 | 7279 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); |
---|
.. | .. |
---|
8978 | 7305 | /* WaProgramL3SqcReg1Default:bdw */ |
---|
8979 | 7306 | gen8_set_l3sqc_credits(dev_priv, 30, 2); |
---|
8980 | 7307 | |
---|
8981 | | - /* WaGttCachingOffByDefault:bdw */ |
---|
8982 | | - I915_WRITE(HSW_GTT_CACHE_EN, can_use_gtt_cache ? GTT_CACHE_EN_ALL : 0); |
---|
8983 | | - |
---|
8984 | 7308 | /* WaKVMNotificationOnConfigChange:bdw */ |
---|
8985 | 7309 | I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1) |
---|
8986 | 7310 | | KVM_CONFIG_CHANGE_NOTIFICATION_SELECT); |
---|
.. | .. |
---|
8998 | 7322 | |
---|
8999 | 7323 | static void hsw_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
9000 | 7324 | { |
---|
9001 | | - /* L3 caching of data atomics doesn't work -- disable it. */ |
---|
9002 | | - I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE); |
---|
9003 | | - I915_WRITE(HSW_ROW_CHICKEN3, |
---|
9004 | | - _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE)); |
---|
| 7325 | + /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ |
---|
| 7326 | + I915_WRITE(CHICKEN_PIPESL_1(PIPE_A), |
---|
| 7327 | + I915_READ(CHICKEN_PIPESL_1(PIPE_A)) | |
---|
| 7328 | + HSW_FBCQ_DIS); |
---|
9005 | 7329 | |
---|
9006 | 7330 | /* This is required by WaCatErrorRejectionIssue:hsw */ |
---|
9007 | 7331 | I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, |
---|
9008 | | - I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | |
---|
9009 | | - GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); |
---|
9010 | | - |
---|
9011 | | - /* WaVSRefCountFullforceMissDisable:hsw */ |
---|
9012 | | - I915_WRITE(GEN7_FF_THREAD_MODE, |
---|
9013 | | - I915_READ(GEN7_FF_THREAD_MODE) & ~GEN7_FF_VS_REF_CNT_FFME); |
---|
9014 | | - |
---|
9015 | | - /* WaDisable_RenderCache_OperationalFlush:hsw */ |
---|
9016 | | - I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
---|
9017 | | - |
---|
9018 | | - /* enable HiZ Raw Stall Optimization */ |
---|
9019 | | - I915_WRITE(CACHE_MODE_0_GEN7, |
---|
9020 | | - _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE)); |
---|
9021 | | - |
---|
9022 | | - /* WaDisable4x2SubspanOptimization:hsw */ |
---|
9023 | | - I915_WRITE(CACHE_MODE_1, |
---|
9024 | | - _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); |
---|
9025 | | - |
---|
9026 | | - /* |
---|
9027 | | - * BSpec recommends 8x4 when MSAA is used, |
---|
9028 | | - * however in practice 16x4 seems fastest. |
---|
9029 | | - * |
---|
9030 | | - * Note that PS/WM thread counts depend on the WIZ hashing |
---|
9031 | | - * disable bit, which we don't touch here, but it's good |
---|
9032 | | - * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). |
---|
9033 | | - */ |
---|
9034 | | - I915_WRITE(GEN7_GT_MODE, |
---|
9035 | | - _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); |
---|
9036 | | - |
---|
9037 | | - /* WaSampleCChickenBitEnable:hsw */ |
---|
9038 | | - I915_WRITE(HALF_SLICE_CHICKEN3, |
---|
9039 | | - _MASKED_BIT_ENABLE(HSW_SAMPLE_C_PERFORMANCE)); |
---|
| 7332 | + I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | |
---|
| 7333 | + GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); |
---|
9040 | 7334 | |
---|
9041 | 7335 | /* WaSwitchSolVfFArbitrationPriority:hsw */ |
---|
9042 | 7336 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); |
---|
.. | .. |
---|
9046 | 7340 | |
---|
9047 | 7341 | static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
9048 | 7342 | { |
---|
9049 | | - uint32_t snpcr; |
---|
| 7343 | + u32 snpcr; |
---|
9050 | 7344 | |
---|
9051 | 7345 | I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); |
---|
9052 | 7346 | |
---|
9053 | | - /* WaDisableEarlyCull:ivb */ |
---|
9054 | | - I915_WRITE(_3D_CHICKEN3, |
---|
9055 | | - _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL)); |
---|
| 7347 | + /* WaFbcAsynchFlipDisableFbcQueue:ivb */ |
---|
| 7348 | + I915_WRITE(ILK_DISPLAY_CHICKEN1, |
---|
| 7349 | + I915_READ(ILK_DISPLAY_CHICKEN1) | |
---|
| 7350 | + ILK_FBCQ_DIS); |
---|
9056 | 7351 | |
---|
9057 | 7352 | /* WaDisableBackToBackFlipFix:ivb */ |
---|
9058 | 7353 | I915_WRITE(IVB_CHICKEN3, |
---|
9059 | 7354 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | |
---|
9060 | 7355 | CHICKEN3_DGMG_DONE_FIX_DISABLE); |
---|
9061 | 7356 | |
---|
9062 | | - /* WaDisablePSDDualDispatchEnable:ivb */ |
---|
9063 | | - if (IS_IVB_GT1(dev_priv)) |
---|
9064 | | - I915_WRITE(GEN7_HALF_SLICE_CHICKEN1, |
---|
9065 | | - _MASKED_BIT_ENABLE(GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE)); |
---|
9066 | | - |
---|
9067 | | - /* WaDisable_RenderCache_OperationalFlush:ivb */ |
---|
9068 | | - I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
---|
9069 | | - |
---|
9070 | | - /* Apply the WaDisableRHWOOptimizationForRenderHang:ivb workaround. */ |
---|
9071 | | - I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, |
---|
9072 | | - GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); |
---|
9073 | | - |
---|
9074 | | - /* WaApplyL3ControlAndL3ChickenMode:ivb */ |
---|
9075 | | - I915_WRITE(GEN7_L3CNTLREG1, |
---|
9076 | | - GEN7_WA_FOR_GEN7_L3_CONTROL); |
---|
9077 | | - I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, |
---|
9078 | | - GEN7_WA_L3_CHICKEN_MODE); |
---|
9079 | 7357 | if (IS_IVB_GT1(dev_priv)) |
---|
9080 | 7358 | I915_WRITE(GEN7_ROW_CHICKEN2, |
---|
9081 | 7359 | _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); |
---|
.. | .. |
---|
9086 | 7364 | I915_WRITE(GEN7_ROW_CHICKEN2_GT2, |
---|
9087 | 7365 | _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); |
---|
9088 | 7366 | } |
---|
9089 | | - |
---|
9090 | | - /* WaForceL3Serialization:ivb */ |
---|
9091 | | - I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) & |
---|
9092 | | - ~L3SQ_URB_READ_CAM_MATCH_DISABLE); |
---|
9093 | 7367 | |
---|
9094 | 7368 | /* |
---|
9095 | 7369 | * According to the spec, bit 13 (RCZUNIT) must be set on IVB. |
---|
.. | .. |
---|
9105 | 7379 | |
---|
9106 | 7380 | g4x_disable_trickle_feed(dev_priv); |
---|
9107 | 7381 | |
---|
9108 | | - gen7_setup_fixed_func_scheduler(dev_priv); |
---|
9109 | | - |
---|
9110 | | - if (0) { /* causes HiZ corruption on ivb:gt1 */ |
---|
9111 | | - /* enable HiZ Raw Stall Optimization */ |
---|
9112 | | - I915_WRITE(CACHE_MODE_0_GEN7, |
---|
9113 | | - _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE)); |
---|
9114 | | - } |
---|
9115 | | - |
---|
9116 | | - /* WaDisable4x2SubspanOptimization:ivb */ |
---|
9117 | | - I915_WRITE(CACHE_MODE_1, |
---|
9118 | | - _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); |
---|
9119 | | - |
---|
9120 | | - /* |
---|
9121 | | - * BSpec recommends 8x4 when MSAA is used, |
---|
9122 | | - * however in practice 16x4 seems fastest. |
---|
9123 | | - * |
---|
9124 | | - * Note that PS/WM thread counts depend on the WIZ hashing |
---|
9125 | | - * disable bit, which we don't touch here, but it's good |
---|
9126 | | - * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). |
---|
9127 | | - */ |
---|
9128 | | - I915_WRITE(GEN7_GT_MODE, |
---|
9129 | | - _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); |
---|
9130 | | - |
---|
9131 | 7382 | snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); |
---|
9132 | 7383 | snpcr &= ~GEN6_MBC_SNPCR_MASK; |
---|
9133 | 7384 | snpcr |= GEN6_MBC_SNPCR_MED; |
---|
.. | .. |
---|
9141 | 7392 | |
---|
9142 | 7393 | static void vlv_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
9143 | 7394 | { |
---|
9144 | | - /* WaDisableEarlyCull:vlv */ |
---|
9145 | | - I915_WRITE(_3D_CHICKEN3, |
---|
9146 | | - _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL)); |
---|
9147 | | - |
---|
9148 | 7395 | /* WaDisableBackToBackFlipFix:vlv */ |
---|
9149 | 7396 | I915_WRITE(IVB_CHICKEN3, |
---|
9150 | 7397 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | |
---|
9151 | 7398 | CHICKEN3_DGMG_DONE_FIX_DISABLE); |
---|
9152 | | - |
---|
9153 | | - /* WaPsdDispatchEnable:vlv */ |
---|
9154 | | - /* WaDisablePSDDualDispatchEnable:vlv */ |
---|
9155 | | - I915_WRITE(GEN7_HALF_SLICE_CHICKEN1, |
---|
9156 | | - _MASKED_BIT_ENABLE(GEN7_MAX_PS_THREAD_DEP | |
---|
9157 | | - GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE)); |
---|
9158 | | - |
---|
9159 | | - /* WaDisable_RenderCache_OperationalFlush:vlv */ |
---|
9160 | | - I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
---|
9161 | | - |
---|
9162 | | - /* WaForceL3Serialization:vlv */ |
---|
9163 | | - I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) & |
---|
9164 | | - ~L3SQ_URB_READ_CAM_MATCH_DISABLE); |
---|
9165 | 7399 | |
---|
9166 | 7400 | /* WaDisableDopClockGating:vlv */ |
---|
9167 | 7401 | I915_WRITE(GEN7_ROW_CHICKEN2, |
---|
.. | .. |
---|
9171 | 7405 | I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, |
---|
9172 | 7406 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | |
---|
9173 | 7407 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); |
---|
9174 | | - |
---|
9175 | | - gen7_setup_fixed_func_scheduler(dev_priv); |
---|
9176 | 7408 | |
---|
9177 | 7409 | /* |
---|
9178 | 7410 | * According to the spec, bit 13 (RCZUNIT) must be set on IVB. |
---|
.. | .. |
---|
9186 | 7418 | * Set bit 25, to disable L3_BANK_2x_CLK_GATING */ |
---|
9187 | 7419 | I915_WRITE(GEN7_UCGCTL4, |
---|
9188 | 7420 | I915_READ(GEN7_UCGCTL4) | GEN7_L3BANK2X_CLOCK_GATE_DISABLE); |
---|
9189 | | - |
---|
9190 | | - /* |
---|
9191 | | - * BSpec says this must be set, even though |
---|
9192 | | - * WaDisable4x2SubspanOptimization isn't listed for VLV. |
---|
9193 | | - */ |
---|
9194 | | - I915_WRITE(CACHE_MODE_1, |
---|
9195 | | - _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE)); |
---|
9196 | | - |
---|
9197 | | - /* |
---|
9198 | | - * BSpec recommends 8x4 when MSAA is used, |
---|
9199 | | - * however in practice 16x4 seems fastest. |
---|
9200 | | - * |
---|
9201 | | - * Note that PS/WM thread counts depend on the WIZ hashing |
---|
9202 | | - * disable bit, which we don't touch here, but it's good |
---|
9203 | | - * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM). |
---|
9204 | | - */ |
---|
9205 | | - I915_WRITE(GEN7_GT_MODE, |
---|
9206 | | - _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); |
---|
9207 | | - |
---|
9208 | | - /* |
---|
9209 | | - * WaIncreaseL3CreditsForVLVB0:vlv |
---|
9210 | | - * This is the hardware default actually. |
---|
9211 | | - */ |
---|
9212 | | - I915_WRITE(GEN7_L3SQCREG1, VLV_B0_WA_L3SQCREG1_VALUE); |
---|
9213 | 7421 | |
---|
9214 | 7422 | /* |
---|
9215 | 7423 | * WaDisableVLVClockGating_VBIIssue:vlv |
---|
.. | .. |
---|
9245 | 7453 | * LSQC Setting Recommendations. |
---|
9246 | 7454 | */ |
---|
9247 | 7455 | gen8_set_l3sqc_credits(dev_priv, 38, 2); |
---|
9248 | | - |
---|
9249 | | - /* |
---|
9250 | | - * GTT cache may not work with big pages, so if those |
---|
9251 | | - * are ever enabled GTT cache may need to be disabled. |
---|
9252 | | - */ |
---|
9253 | | - I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL); |
---|
9254 | 7456 | } |
---|
9255 | 7457 | |
---|
9256 | 7458 | static void g4x_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
9257 | 7459 | { |
---|
9258 | | - uint32_t dspclk_gate; |
---|
| 7460 | + u32 dspclk_gate; |
---|
9259 | 7461 | |
---|
9260 | 7462 | I915_WRITE(RENCLK_GATE_D1, 0); |
---|
9261 | 7463 | I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | |
---|
.. | .. |
---|
9269 | 7471 | dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; |
---|
9270 | 7472 | I915_WRITE(DSPCLK_GATE_D, dspclk_gate); |
---|
9271 | 7473 | |
---|
9272 | | - /* WaDisableRenderCachePipelinedFlush */ |
---|
9273 | | - I915_WRITE(CACHE_MODE_0, |
---|
9274 | | - _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE)); |
---|
9275 | | - |
---|
9276 | | - /* WaDisable_RenderCache_OperationalFlush:g4x */ |
---|
9277 | | - I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
---|
9278 | | - |
---|
9279 | 7474 | g4x_disable_trickle_feed(dev_priv); |
---|
9280 | 7475 | } |
---|
9281 | 7476 | |
---|
9282 | 7477 | static void i965gm_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
9283 | 7478 | { |
---|
9284 | | - I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); |
---|
9285 | | - I915_WRITE(RENCLK_GATE_D2, 0); |
---|
9286 | | - I915_WRITE(DSPCLK_GATE_D, 0); |
---|
9287 | | - I915_WRITE(RAMCLK_GATE_D, 0); |
---|
9288 | | - I915_WRITE16(DEUC, 0); |
---|
9289 | | - I915_WRITE(MI_ARB_STATE, |
---|
9290 | | - _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); |
---|
| 7479 | + struct intel_uncore *uncore = &dev_priv->uncore; |
---|
9291 | 7480 | |
---|
9292 | | - /* WaDisable_RenderCache_OperationalFlush:gen4 */ |
---|
9293 | | - I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
---|
| 7481 | + intel_uncore_write(uncore, RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); |
---|
| 7482 | + intel_uncore_write(uncore, RENCLK_GATE_D2, 0); |
---|
| 7483 | + intel_uncore_write(uncore, DSPCLK_GATE_D, 0); |
---|
| 7484 | + intel_uncore_write(uncore, RAMCLK_GATE_D, 0); |
---|
| 7485 | + intel_uncore_write16(uncore, DEUC, 0); |
---|
| 7486 | + intel_uncore_write(uncore, |
---|
| 7487 | + MI_ARB_STATE, |
---|
| 7488 | + _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); |
---|
9294 | 7489 | } |
---|
9295 | 7490 | |
---|
9296 | 7491 | static void i965g_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
.. | .. |
---|
9303 | 7498 | I915_WRITE(RENCLK_GATE_D2, 0); |
---|
9304 | 7499 | I915_WRITE(MI_ARB_STATE, |
---|
9305 | 7500 | _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); |
---|
9306 | | - |
---|
9307 | | - /* WaDisable_RenderCache_OperationalFlush:gen4 */ |
---|
9308 | | - I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE)); |
---|
9309 | 7501 | } |
---|
9310 | 7502 | |
---|
9311 | 7503 | static void gen3_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
.. | .. |
---|
9342 | 7534 | |
---|
9343 | 7535 | I915_WRITE(MEM_MODE, |
---|
9344 | 7536 | _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE)); |
---|
| 7537 | + |
---|
| 7538 | + /* |
---|
| 7539 | + * Have FBC ignore 3D activity since we use software |
---|
| 7540 | + * render tracking, and otherwise a pure 3D workload |
---|
| 7541 | + * (even if it just renders a single frame and then does |
---|
| 7542 | + * abosultely nothing) would not allow FBC to recompress |
---|
| 7543 | + * until a 2D blit occurs. |
---|
| 7544 | + */ |
---|
| 7545 | + I915_WRITE(SCPD0, |
---|
| 7546 | + _MASKED_BIT_ENABLE(SCPD_FBC_IGNORE_3D)); |
---|
9345 | 7547 | } |
---|
9346 | 7548 | |
---|
9347 | 7549 | static void i830_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
.. | .. |
---|
9364 | 7566 | |
---|
9365 | 7567 | static void nop_init_clock_gating(struct drm_i915_private *dev_priv) |
---|
9366 | 7568 | { |
---|
9367 | | - DRM_DEBUG_KMS("No clock gating settings or workarounds applied.\n"); |
---|
| 7569 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 7570 | + "No clock gating settings or workarounds applied.\n"); |
---|
9368 | 7571 | } |
---|
9369 | 7572 | |
---|
9370 | 7573 | /** |
---|
.. | .. |
---|
9378 | 7581 | */ |
---|
9379 | 7582 | void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) |
---|
9380 | 7583 | { |
---|
9381 | | - if (IS_ICELAKE(dev_priv)) |
---|
| 7584 | + if (IS_GEN(dev_priv, 12)) |
---|
| 7585 | + dev_priv->display.init_clock_gating = tgl_init_clock_gating; |
---|
| 7586 | + else if (IS_GEN(dev_priv, 11)) |
---|
9382 | 7587 | dev_priv->display.init_clock_gating = icl_init_clock_gating; |
---|
9383 | 7588 | else if (IS_CANNONLAKE(dev_priv)) |
---|
9384 | 7589 | dev_priv->display.init_clock_gating = cnl_init_clock_gating; |
---|
9385 | | - else if (IS_COFFEELAKE(dev_priv)) |
---|
| 7590 | + else if (IS_COFFEELAKE(dev_priv) || IS_COMETLAKE(dev_priv)) |
---|
9386 | 7591 | dev_priv->display.init_clock_gating = cfl_init_clock_gating; |
---|
9387 | 7592 | else if (IS_SKYLAKE(dev_priv)) |
---|
9388 | 7593 | dev_priv->display.init_clock_gating = skl_init_clock_gating; |
---|
.. | .. |
---|
9402 | 7607 | dev_priv->display.init_clock_gating = ivb_init_clock_gating; |
---|
9403 | 7608 | else if (IS_VALLEYVIEW(dev_priv)) |
---|
9404 | 7609 | dev_priv->display.init_clock_gating = vlv_init_clock_gating; |
---|
9405 | | - else if (IS_GEN6(dev_priv)) |
---|
| 7610 | + else if (IS_GEN(dev_priv, 6)) |
---|
9406 | 7611 | dev_priv->display.init_clock_gating = gen6_init_clock_gating; |
---|
9407 | | - else if (IS_GEN5(dev_priv)) |
---|
| 7612 | + else if (IS_GEN(dev_priv, 5)) |
---|
9408 | 7613 | dev_priv->display.init_clock_gating = ilk_init_clock_gating; |
---|
9409 | 7614 | else if (IS_G4X(dev_priv)) |
---|
9410 | 7615 | dev_priv->display.init_clock_gating = g4x_init_clock_gating; |
---|
.. | .. |
---|
9412 | 7617 | dev_priv->display.init_clock_gating = i965gm_init_clock_gating; |
---|
9413 | 7618 | else if (IS_I965G(dev_priv)) |
---|
9414 | 7619 | dev_priv->display.init_clock_gating = i965g_init_clock_gating; |
---|
9415 | | - else if (IS_GEN3(dev_priv)) |
---|
| 7620 | + else if (IS_GEN(dev_priv, 3)) |
---|
9416 | 7621 | dev_priv->display.init_clock_gating = gen3_init_clock_gating; |
---|
9417 | 7622 | else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) |
---|
9418 | 7623 | dev_priv->display.init_clock_gating = i85x_init_clock_gating; |
---|
9419 | | - else if (IS_GEN2(dev_priv)) |
---|
| 7624 | + else if (IS_GEN(dev_priv, 2)) |
---|
9420 | 7625 | dev_priv->display.init_clock_gating = i830_init_clock_gating; |
---|
9421 | 7626 | else { |
---|
9422 | 7627 | MISSING_CASE(INTEL_DEVID(dev_priv)); |
---|
.. | .. |
---|
9427 | 7632 | /* Set up chip specific power management-related functions */ |
---|
9428 | 7633 | void intel_init_pm(struct drm_i915_private *dev_priv) |
---|
9429 | 7634 | { |
---|
9430 | | - intel_fbc_init(dev_priv); |
---|
9431 | | - |
---|
9432 | 7635 | /* For cxsr */ |
---|
9433 | 7636 | if (IS_PINEVIEW(dev_priv)) |
---|
9434 | | - i915_pineview_get_mem_freq(dev_priv); |
---|
9435 | | - else if (IS_GEN5(dev_priv)) |
---|
9436 | | - i915_ironlake_get_mem_freq(dev_priv); |
---|
| 7637 | + pnv_get_mem_freq(dev_priv); |
---|
| 7638 | + else if (IS_GEN(dev_priv, 5)) |
---|
| 7639 | + ilk_get_mem_freq(dev_priv); |
---|
| 7640 | + |
---|
| 7641 | + if (intel_has_sagv(dev_priv)) |
---|
| 7642 | + skl_setup_sagv_block_time(dev_priv); |
---|
9437 | 7643 | |
---|
9438 | 7644 | /* For FIFO watermark updates */ |
---|
9439 | 7645 | if (INTEL_GEN(dev_priv) >= 9) { |
---|
9440 | 7646 | skl_setup_wm_latency(dev_priv); |
---|
9441 | | - dev_priv->display.initial_watermarks = skl_initial_wm; |
---|
9442 | | - dev_priv->display.atomic_update_watermarks = skl_atomic_update_crtc_wm; |
---|
9443 | 7647 | dev_priv->display.compute_global_watermarks = skl_compute_wm; |
---|
9444 | 7648 | } else if (HAS_PCH_SPLIT(dev_priv)) { |
---|
9445 | 7649 | ilk_setup_wm_latency(dev_priv); |
---|
9446 | 7650 | |
---|
9447 | | - if ((IS_GEN5(dev_priv) && dev_priv->wm.pri_latency[1] && |
---|
| 7651 | + if ((IS_GEN(dev_priv, 5) && dev_priv->wm.pri_latency[1] && |
---|
9448 | 7652 | dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) || |
---|
9449 | | - (!IS_GEN5(dev_priv) && dev_priv->wm.pri_latency[0] && |
---|
| 7653 | + (!IS_GEN(dev_priv, 5) && dev_priv->wm.pri_latency[0] && |
---|
9450 | 7654 | dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { |
---|
9451 | 7655 | dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm; |
---|
9452 | 7656 | dev_priv->display.compute_intermediate_wm = |
---|
.. | .. |
---|
9456 | 7660 | dev_priv->display.optimize_watermarks = |
---|
9457 | 7661 | ilk_optimize_watermarks; |
---|
9458 | 7662 | } else { |
---|
9459 | | - DRM_DEBUG_KMS("Failed to read display plane latency. " |
---|
9460 | | - "Disable CxSR\n"); |
---|
| 7663 | + drm_dbg_kms(&dev_priv->drm, |
---|
| 7664 | + "Failed to read display plane latency. " |
---|
| 7665 | + "Disable CxSR\n"); |
---|
9461 | 7666 | } |
---|
9462 | 7667 | } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { |
---|
9463 | 7668 | vlv_setup_wm_latency(dev_priv); |
---|
.. | .. |
---|
9473 | 7678 | dev_priv->display.initial_watermarks = g4x_initial_watermarks; |
---|
9474 | 7679 | dev_priv->display.optimize_watermarks = g4x_optimize_watermarks; |
---|
9475 | 7680 | } else if (IS_PINEVIEW(dev_priv)) { |
---|
9476 | | - if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev_priv), |
---|
| 7681 | + if (!intel_get_cxsr_latency(!IS_MOBILE(dev_priv), |
---|
9477 | 7682 | dev_priv->is_ddr3, |
---|
9478 | 7683 | dev_priv->fsb_freq, |
---|
9479 | 7684 | dev_priv->mem_freq)) { |
---|
9480 | | - DRM_INFO("failed to find known CxSR latency " |
---|
| 7685 | + drm_info(&dev_priv->drm, |
---|
| 7686 | + "failed to find known CxSR latency " |
---|
9481 | 7687 | "(found ddr%s fsb freq %d, mem freq %d), " |
---|
9482 | 7688 | "disabling CxSR\n", |
---|
9483 | 7689 | (dev_priv->is_ddr3 == 1) ? "3" : "2", |
---|
.. | .. |
---|
9486 | 7692 | intel_set_memory_cxsr(dev_priv, false); |
---|
9487 | 7693 | dev_priv->display.update_wm = NULL; |
---|
9488 | 7694 | } else |
---|
9489 | | - dev_priv->display.update_wm = pineview_update_wm; |
---|
9490 | | - } else if (IS_GEN4(dev_priv)) { |
---|
| 7695 | + dev_priv->display.update_wm = pnv_update_wm; |
---|
| 7696 | + } else if (IS_GEN(dev_priv, 4)) { |
---|
9491 | 7697 | dev_priv->display.update_wm = i965_update_wm; |
---|
9492 | | - } else if (IS_GEN3(dev_priv)) { |
---|
| 7698 | + } else if (IS_GEN(dev_priv, 3)) { |
---|
9493 | 7699 | dev_priv->display.update_wm = i9xx_update_wm; |
---|
9494 | 7700 | dev_priv->display.get_fifo_size = i9xx_get_fifo_size; |
---|
9495 | | - } else if (IS_GEN2(dev_priv)) { |
---|
9496 | | - if (INTEL_INFO(dev_priv)->num_pipes == 1) { |
---|
| 7701 | + } else if (IS_GEN(dev_priv, 2)) { |
---|
| 7702 | + if (INTEL_NUM_PIPES(dev_priv) == 1) { |
---|
9497 | 7703 | dev_priv->display.update_wm = i845_update_wm; |
---|
9498 | 7704 | dev_priv->display.get_fifo_size = i845_get_fifo_size; |
---|
9499 | 7705 | } else { |
---|
.. | .. |
---|
9501 | 7707 | dev_priv->display.get_fifo_size = i830_get_fifo_size; |
---|
9502 | 7708 | } |
---|
9503 | 7709 | } else { |
---|
9504 | | - DRM_ERROR("unexpected fall-through in intel_init_pm\n"); |
---|
| 7710 | + drm_err(&dev_priv->drm, |
---|
| 7711 | + "unexpected fall-through in %s\n", __func__); |
---|
9505 | 7712 | } |
---|
9506 | | -} |
---|
9507 | | - |
---|
9508 | | -static inline int gen6_check_mailbox_status(struct drm_i915_private *dev_priv) |
---|
9509 | | -{ |
---|
9510 | | - uint32_t flags = |
---|
9511 | | - I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK; |
---|
9512 | | - |
---|
9513 | | - switch (flags) { |
---|
9514 | | - case GEN6_PCODE_SUCCESS: |
---|
9515 | | - return 0; |
---|
9516 | | - case GEN6_PCODE_UNIMPLEMENTED_CMD: |
---|
9517 | | - return -ENODEV; |
---|
9518 | | - case GEN6_PCODE_ILLEGAL_CMD: |
---|
9519 | | - return -ENXIO; |
---|
9520 | | - case GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: |
---|
9521 | | - case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: |
---|
9522 | | - return -EOVERFLOW; |
---|
9523 | | - case GEN6_PCODE_TIMEOUT: |
---|
9524 | | - return -ETIMEDOUT; |
---|
9525 | | - default: |
---|
9526 | | - MISSING_CASE(flags); |
---|
9527 | | - return 0; |
---|
9528 | | - } |
---|
9529 | | -} |
---|
9530 | | - |
---|
9531 | | -static inline int gen7_check_mailbox_status(struct drm_i915_private *dev_priv) |
---|
9532 | | -{ |
---|
9533 | | - uint32_t flags = |
---|
9534 | | - I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK; |
---|
9535 | | - |
---|
9536 | | - switch (flags) { |
---|
9537 | | - case GEN6_PCODE_SUCCESS: |
---|
9538 | | - return 0; |
---|
9539 | | - case GEN6_PCODE_ILLEGAL_CMD: |
---|
9540 | | - return -ENXIO; |
---|
9541 | | - case GEN7_PCODE_TIMEOUT: |
---|
9542 | | - return -ETIMEDOUT; |
---|
9543 | | - case GEN7_PCODE_ILLEGAL_DATA: |
---|
9544 | | - return -EINVAL; |
---|
9545 | | - case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: |
---|
9546 | | - return -EOVERFLOW; |
---|
9547 | | - default: |
---|
9548 | | - MISSING_CASE(flags); |
---|
9549 | | - return 0; |
---|
9550 | | - } |
---|
9551 | | -} |
---|
9552 | | - |
---|
9553 | | -int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val) |
---|
9554 | | -{ |
---|
9555 | | - int status; |
---|
9556 | | - |
---|
9557 | | - WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); |
---|
9558 | | - |
---|
9559 | | - /* GEN6_PCODE_* are outside of the forcewake domain, we can |
---|
9560 | | - * use te fw I915_READ variants to reduce the amount of work |
---|
9561 | | - * required when reading/writing. |
---|
9562 | | - */ |
---|
9563 | | - |
---|
9564 | | - if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) { |
---|
9565 | | - DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps\n", |
---|
9566 | | - mbox, __builtin_return_address(0)); |
---|
9567 | | - return -EAGAIN; |
---|
9568 | | - } |
---|
9569 | | - |
---|
9570 | | - I915_WRITE_FW(GEN6_PCODE_DATA, *val); |
---|
9571 | | - I915_WRITE_FW(GEN6_PCODE_DATA1, 0); |
---|
9572 | | - I915_WRITE_FW(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox); |
---|
9573 | | - |
---|
9574 | | - if (__intel_wait_for_register_fw(dev_priv, |
---|
9575 | | - GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0, |
---|
9576 | | - 500, 0, NULL)) { |
---|
9577 | | - DRM_ERROR("timeout waiting for pcode read (from mbox %x) to finish for %ps\n", |
---|
9578 | | - mbox, __builtin_return_address(0)); |
---|
9579 | | - return -ETIMEDOUT; |
---|
9580 | | - } |
---|
9581 | | - |
---|
9582 | | - *val = I915_READ_FW(GEN6_PCODE_DATA); |
---|
9583 | | - I915_WRITE_FW(GEN6_PCODE_DATA, 0); |
---|
9584 | | - |
---|
9585 | | - if (INTEL_GEN(dev_priv) > 6) |
---|
9586 | | - status = gen7_check_mailbox_status(dev_priv); |
---|
9587 | | - else |
---|
9588 | | - status = gen6_check_mailbox_status(dev_priv); |
---|
9589 | | - |
---|
9590 | | - if (status) { |
---|
9591 | | - DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps: %d\n", |
---|
9592 | | - mbox, __builtin_return_address(0), status); |
---|
9593 | | - return status; |
---|
9594 | | - } |
---|
9595 | | - |
---|
9596 | | - return 0; |
---|
9597 | | -} |
---|
9598 | | - |
---|
9599 | | -int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv, |
---|
9600 | | - u32 mbox, u32 val, |
---|
9601 | | - int fast_timeout_us, int slow_timeout_ms) |
---|
9602 | | -{ |
---|
9603 | | - int status; |
---|
9604 | | - |
---|
9605 | | - WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); |
---|
9606 | | - |
---|
9607 | | - /* GEN6_PCODE_* are outside of the forcewake domain, we can |
---|
9608 | | - * use te fw I915_READ variants to reduce the amount of work |
---|
9609 | | - * required when reading/writing. |
---|
9610 | | - */ |
---|
9611 | | - |
---|
9612 | | - if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) { |
---|
9613 | | - DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps\n", |
---|
9614 | | - val, mbox, __builtin_return_address(0)); |
---|
9615 | | - return -EAGAIN; |
---|
9616 | | - } |
---|
9617 | | - |
---|
9618 | | - I915_WRITE_FW(GEN6_PCODE_DATA, val); |
---|
9619 | | - I915_WRITE_FW(GEN6_PCODE_DATA1, 0); |
---|
9620 | | - I915_WRITE_FW(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox); |
---|
9621 | | - |
---|
9622 | | - if (__intel_wait_for_register_fw(dev_priv, |
---|
9623 | | - GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0, |
---|
9624 | | - fast_timeout_us, slow_timeout_ms, |
---|
9625 | | - NULL)) { |
---|
9626 | | - DRM_ERROR("timeout waiting for pcode write of 0x%08x to mbox %x to finish for %ps\n", |
---|
9627 | | - val, mbox, __builtin_return_address(0)); |
---|
9628 | | - return -ETIMEDOUT; |
---|
9629 | | - } |
---|
9630 | | - |
---|
9631 | | - I915_WRITE_FW(GEN6_PCODE_DATA, 0); |
---|
9632 | | - |
---|
9633 | | - if (INTEL_GEN(dev_priv) > 6) |
---|
9634 | | - status = gen7_check_mailbox_status(dev_priv); |
---|
9635 | | - else |
---|
9636 | | - status = gen6_check_mailbox_status(dev_priv); |
---|
9637 | | - |
---|
9638 | | - if (status) { |
---|
9639 | | - DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps: %d\n", |
---|
9640 | | - val, mbox, __builtin_return_address(0), status); |
---|
9641 | | - return status; |
---|
9642 | | - } |
---|
9643 | | - |
---|
9644 | | - return 0; |
---|
9645 | | -} |
---|
9646 | | - |
---|
9647 | | -static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox, |
---|
9648 | | - u32 request, u32 reply_mask, u32 reply, |
---|
9649 | | - u32 *status) |
---|
9650 | | -{ |
---|
9651 | | - u32 val = request; |
---|
9652 | | - |
---|
9653 | | - *status = sandybridge_pcode_read(dev_priv, mbox, &val); |
---|
9654 | | - |
---|
9655 | | - return *status || ((val & reply_mask) == reply); |
---|
9656 | | -} |
---|
9657 | | - |
---|
9658 | | -/** |
---|
9659 | | - * skl_pcode_request - send PCODE request until acknowledgment |
---|
9660 | | - * @dev_priv: device private |
---|
9661 | | - * @mbox: PCODE mailbox ID the request is targeted for |
---|
9662 | | - * @request: request ID |
---|
9663 | | - * @reply_mask: mask used to check for request acknowledgment |
---|
9664 | | - * @reply: value used to check for request acknowledgment |
---|
9665 | | - * @timeout_base_ms: timeout for polling with preemption enabled |
---|
9666 | | - * |
---|
9667 | | - * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE |
---|
9668 | | - * reports an error or an overall timeout of @timeout_base_ms+50 ms expires. |
---|
9669 | | - * The request is acknowledged once the PCODE reply dword equals @reply after |
---|
9670 | | - * applying @reply_mask. Polling is first attempted with preemption enabled |
---|
9671 | | - * for @timeout_base_ms and if this times out for another 50 ms with |
---|
9672 | | - * preemption disabled. |
---|
9673 | | - * |
---|
9674 | | - * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some |
---|
9675 | | - * other error as reported by PCODE. |
---|
9676 | | - */ |
---|
9677 | | -int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request, |
---|
9678 | | - u32 reply_mask, u32 reply, int timeout_base_ms) |
---|
9679 | | -{ |
---|
9680 | | - u32 status; |
---|
9681 | | - int ret; |
---|
9682 | | - |
---|
9683 | | - WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock)); |
---|
9684 | | - |
---|
9685 | | -#define COND skl_pcode_try_request(dev_priv, mbox, request, reply_mask, reply, \ |
---|
9686 | | - &status) |
---|
9687 | | - |
---|
9688 | | - /* |
---|
9689 | | - * Prime the PCODE by doing a request first. Normally it guarantees |
---|
9690 | | - * that a subsequent request, at most @timeout_base_ms later, succeeds. |
---|
9691 | | - * _wait_for() doesn't guarantee when its passed condition is evaluated |
---|
9692 | | - * first, so send the first request explicitly. |
---|
9693 | | - */ |
---|
9694 | | - if (COND) { |
---|
9695 | | - ret = 0; |
---|
9696 | | - goto out; |
---|
9697 | | - } |
---|
9698 | | - ret = _wait_for(COND, timeout_base_ms * 1000, 10, 10); |
---|
9699 | | - if (!ret) |
---|
9700 | | - goto out; |
---|
9701 | | - |
---|
9702 | | - /* |
---|
9703 | | - * The above can time out if the number of requests was low (2 in the |
---|
9704 | | - * worst case) _and_ PCODE was busy for some reason even after a |
---|
9705 | | - * (queued) request and @timeout_base_ms delay. As a workaround retry |
---|
9706 | | - * the poll with preemption disabled to maximize the number of |
---|
9707 | | - * requests. Increase the timeout from @timeout_base_ms to 50ms to |
---|
9708 | | - * account for interrupts that could reduce the number of these |
---|
9709 | | - * requests, and for any quirks of the PCODE firmware that delays |
---|
9710 | | - * the request completion. |
---|
9711 | | - */ |
---|
9712 | | - DRM_DEBUG_KMS("PCODE timeout, retrying with preemption disabled\n"); |
---|
9713 | | - WARN_ON_ONCE(timeout_base_ms > 3); |
---|
9714 | | - preempt_disable(); |
---|
9715 | | - ret = wait_for_atomic(COND, 50); |
---|
9716 | | - preempt_enable(); |
---|
9717 | | - |
---|
9718 | | -out: |
---|
9719 | | - return ret ? ret : status; |
---|
9720 | | -#undef COND |
---|
9721 | | -} |
---|
9722 | | - |
---|
9723 | | -static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) |
---|
9724 | | -{ |
---|
9725 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
9726 | | - |
---|
9727 | | - /* |
---|
9728 | | - * N = val - 0xb7 |
---|
9729 | | - * Slow = Fast = GPLL ref * N |
---|
9730 | | - */ |
---|
9731 | | - return DIV_ROUND_CLOSEST(rps->gpll_ref_freq * (val - 0xb7), 1000); |
---|
9732 | | -} |
---|
9733 | | - |
---|
9734 | | -static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) |
---|
9735 | | -{ |
---|
9736 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
9737 | | - |
---|
9738 | | - return DIV_ROUND_CLOSEST(1000 * val, rps->gpll_ref_freq) + 0xb7; |
---|
9739 | | -} |
---|
9740 | | - |
---|
9741 | | -static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) |
---|
9742 | | -{ |
---|
9743 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
9744 | | - |
---|
9745 | | - /* |
---|
9746 | | - * N = val / 2 |
---|
9747 | | - * CU (slow) = CU2x (fast) / 2 = GPLL ref * N / 2 |
---|
9748 | | - */ |
---|
9749 | | - return DIV_ROUND_CLOSEST(rps->gpll_ref_freq * val, 2 * 2 * 1000); |
---|
9750 | | -} |
---|
9751 | | - |
---|
9752 | | -static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) |
---|
9753 | | -{ |
---|
9754 | | - struct intel_rps *rps = &dev_priv->gt_pm.rps; |
---|
9755 | | - |
---|
9756 | | - /* CHV needs even values */ |
---|
9757 | | - return DIV_ROUND_CLOSEST(2 * 1000 * val, rps->gpll_ref_freq) * 2; |
---|
9758 | | -} |
---|
9759 | | - |
---|
9760 | | -int intel_gpu_freq(struct drm_i915_private *dev_priv, int val) |
---|
9761 | | -{ |
---|
9762 | | - if (INTEL_GEN(dev_priv) >= 9) |
---|
9763 | | - return DIV_ROUND_CLOSEST(val * GT_FREQUENCY_MULTIPLIER, |
---|
9764 | | - GEN9_FREQ_SCALER); |
---|
9765 | | - else if (IS_CHERRYVIEW(dev_priv)) |
---|
9766 | | - return chv_gpu_freq(dev_priv, val); |
---|
9767 | | - else if (IS_VALLEYVIEW(dev_priv)) |
---|
9768 | | - return byt_gpu_freq(dev_priv, val); |
---|
9769 | | - else |
---|
9770 | | - return val * GT_FREQUENCY_MULTIPLIER; |
---|
9771 | | -} |
---|
9772 | | - |
---|
9773 | | -int intel_freq_opcode(struct drm_i915_private *dev_priv, int val) |
---|
9774 | | -{ |
---|
9775 | | - if (INTEL_GEN(dev_priv) >= 9) |
---|
9776 | | - return DIV_ROUND_CLOSEST(val * GEN9_FREQ_SCALER, |
---|
9777 | | - GT_FREQUENCY_MULTIPLIER); |
---|
9778 | | - else if (IS_CHERRYVIEW(dev_priv)) |
---|
9779 | | - return chv_freq_opcode(dev_priv, val); |
---|
9780 | | - else if (IS_VALLEYVIEW(dev_priv)) |
---|
9781 | | - return byt_freq_opcode(dev_priv, val); |
---|
9782 | | - else |
---|
9783 | | - return DIV_ROUND_CLOSEST(val, GT_FREQUENCY_MULTIPLIER); |
---|
9784 | 7713 | } |
---|
9785 | 7714 | |
---|
9786 | 7715 | void intel_pm_setup(struct drm_i915_private *dev_priv) |
---|
9787 | 7716 | { |
---|
9788 | | - mutex_init(&dev_priv->pcu_lock); |
---|
9789 | | - mutex_init(&dev_priv->gt_pm.rps.power.mutex); |
---|
9790 | | - |
---|
9791 | | - atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0); |
---|
9792 | | - |
---|
9793 | 7717 | dev_priv->runtime_pm.suspended = false; |
---|
9794 | 7718 | atomic_set(&dev_priv->runtime_pm.wakeref_count, 0); |
---|
9795 | 7719 | } |
---|
9796 | 7720 | |
---|
9797 | | -static u64 vlv_residency_raw(struct drm_i915_private *dev_priv, |
---|
9798 | | - const i915_reg_t reg) |
---|
| 7721 | +static struct intel_global_state *intel_dbuf_duplicate_state(struct intel_global_obj *obj) |
---|
9799 | 7722 | { |
---|
9800 | | - u32 lower, upper, tmp; |
---|
9801 | | - int loop = 2; |
---|
| 7723 | + struct intel_dbuf_state *dbuf_state; |
---|
9802 | 7724 | |
---|
9803 | | - /* |
---|
9804 | | - * The register accessed do not need forcewake. We borrow |
---|
9805 | | - * uncore lock to prevent concurrent access to range reg. |
---|
9806 | | - */ |
---|
9807 | | - lockdep_assert_held(&dev_priv->uncore.lock); |
---|
| 7725 | + dbuf_state = kmemdup(obj->state, sizeof(*dbuf_state), GFP_KERNEL); |
---|
| 7726 | + if (!dbuf_state) |
---|
| 7727 | + return NULL; |
---|
9808 | 7728 | |
---|
9809 | | - /* |
---|
9810 | | - * vlv and chv residency counters are 40 bits in width. |
---|
9811 | | - * With a control bit, we can choose between upper or lower |
---|
9812 | | - * 32bit window into this counter. |
---|
9813 | | - * |
---|
9814 | | - * Although we always use the counter in high-range mode elsewhere, |
---|
9815 | | - * userspace may attempt to read the value before rc6 is initialised, |
---|
9816 | | - * before we have set the default VLV_COUNTER_CONTROL value. So always |
---|
9817 | | - * set the high bit to be safe. |
---|
9818 | | - */ |
---|
9819 | | - I915_WRITE_FW(VLV_COUNTER_CONTROL, |
---|
9820 | | - _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH)); |
---|
9821 | | - upper = I915_READ_FW(reg); |
---|
9822 | | - do { |
---|
9823 | | - tmp = upper; |
---|
9824 | | - |
---|
9825 | | - I915_WRITE_FW(VLV_COUNTER_CONTROL, |
---|
9826 | | - _MASKED_BIT_DISABLE(VLV_COUNT_RANGE_HIGH)); |
---|
9827 | | - lower = I915_READ_FW(reg); |
---|
9828 | | - |
---|
9829 | | - I915_WRITE_FW(VLV_COUNTER_CONTROL, |
---|
9830 | | - _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH)); |
---|
9831 | | - upper = I915_READ_FW(reg); |
---|
9832 | | - } while (upper != tmp && --loop); |
---|
9833 | | - |
---|
9834 | | - /* |
---|
9835 | | - * Everywhere else we always use VLV_COUNTER_CONTROL with the |
---|
9836 | | - * VLV_COUNT_RANGE_HIGH bit set - so it is safe to leave it set |
---|
9837 | | - * now. |
---|
9838 | | - */ |
---|
9839 | | - |
---|
9840 | | - return lower | (u64)upper << 8; |
---|
| 7729 | + return &dbuf_state->base; |
---|
9841 | 7730 | } |
---|
9842 | 7731 | |
---|
9843 | | -u64 intel_rc6_residency_ns(struct drm_i915_private *dev_priv, |
---|
9844 | | - const i915_reg_t reg) |
---|
| 7732 | +static void intel_dbuf_destroy_state(struct intel_global_obj *obj, |
---|
| 7733 | + struct intel_global_state *state) |
---|
9845 | 7734 | { |
---|
9846 | | - u64 time_hw, prev_hw, overflow_hw; |
---|
9847 | | - unsigned int fw_domains; |
---|
9848 | | - unsigned long flags; |
---|
9849 | | - unsigned int i; |
---|
9850 | | - u32 mul, div; |
---|
9851 | | - |
---|
9852 | | - if (!HAS_RC6(dev_priv)) |
---|
9853 | | - return 0; |
---|
9854 | | - |
---|
9855 | | - /* |
---|
9856 | | - * Store previous hw counter values for counter wrap-around handling. |
---|
9857 | | - * |
---|
9858 | | - * There are only four interesting registers and they live next to each |
---|
9859 | | - * other so we can use the relative address, compared to the smallest |
---|
9860 | | - * one as the index into driver storage. |
---|
9861 | | - */ |
---|
9862 | | - i = (i915_mmio_reg_offset(reg) - |
---|
9863 | | - i915_mmio_reg_offset(GEN6_GT_GFX_RC6_LOCKED)) / sizeof(u32); |
---|
9864 | | - if (WARN_ON_ONCE(i >= ARRAY_SIZE(dev_priv->gt_pm.rc6.cur_residency))) |
---|
9865 | | - return 0; |
---|
9866 | | - |
---|
9867 | | - fw_domains = intel_uncore_forcewake_for_reg(dev_priv, reg, FW_REG_READ); |
---|
9868 | | - |
---|
9869 | | - spin_lock_irqsave(&dev_priv->uncore.lock, flags); |
---|
9870 | | - intel_uncore_forcewake_get__locked(dev_priv, fw_domains); |
---|
9871 | | - |
---|
9872 | | - /* On VLV and CHV, residency time is in CZ units rather than 1.28us */ |
---|
9873 | | - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { |
---|
9874 | | - mul = 1000000; |
---|
9875 | | - div = dev_priv->czclk_freq; |
---|
9876 | | - overflow_hw = BIT_ULL(40); |
---|
9877 | | - time_hw = vlv_residency_raw(dev_priv, reg); |
---|
9878 | | - } else { |
---|
9879 | | - /* 833.33ns units on Gen9LP, 1.28us elsewhere. */ |
---|
9880 | | - if (IS_GEN9_LP(dev_priv)) { |
---|
9881 | | - mul = 10000; |
---|
9882 | | - div = 12; |
---|
9883 | | - } else { |
---|
9884 | | - mul = 1280; |
---|
9885 | | - div = 1; |
---|
9886 | | - } |
---|
9887 | | - |
---|
9888 | | - overflow_hw = BIT_ULL(32); |
---|
9889 | | - time_hw = I915_READ_FW(reg); |
---|
9890 | | - } |
---|
9891 | | - |
---|
9892 | | - /* |
---|
9893 | | - * Counter wrap handling. |
---|
9894 | | - * |
---|
9895 | | - * But relying on a sufficient frequency of queries otherwise counters |
---|
9896 | | - * can still wrap. |
---|
9897 | | - */ |
---|
9898 | | - prev_hw = dev_priv->gt_pm.rc6.prev_hw_residency[i]; |
---|
9899 | | - dev_priv->gt_pm.rc6.prev_hw_residency[i] = time_hw; |
---|
9900 | | - |
---|
9901 | | - /* RC6 delta from last sample. */ |
---|
9902 | | - if (time_hw >= prev_hw) |
---|
9903 | | - time_hw -= prev_hw; |
---|
9904 | | - else |
---|
9905 | | - time_hw += overflow_hw - prev_hw; |
---|
9906 | | - |
---|
9907 | | - /* Add delta to RC6 extended raw driver copy. */ |
---|
9908 | | - time_hw += dev_priv->gt_pm.rc6.cur_residency[i]; |
---|
9909 | | - dev_priv->gt_pm.rc6.cur_residency[i] = time_hw; |
---|
9910 | | - |
---|
9911 | | - intel_uncore_forcewake_put__locked(dev_priv, fw_domains); |
---|
9912 | | - spin_unlock_irqrestore(&dev_priv->uncore.lock, flags); |
---|
9913 | | - |
---|
9914 | | - return mul_u64_u32_div(time_hw, mul, div); |
---|
| 7735 | + kfree(state); |
---|
9915 | 7736 | } |
---|
9916 | 7737 | |
---|
9917 | | -u32 intel_get_cagf(struct drm_i915_private *dev_priv, u32 rpstat) |
---|
| 7738 | +static const struct intel_global_state_funcs intel_dbuf_funcs = { |
---|
| 7739 | + .atomic_duplicate_state = intel_dbuf_duplicate_state, |
---|
| 7740 | + .atomic_destroy_state = intel_dbuf_destroy_state, |
---|
| 7741 | +}; |
---|
| 7742 | + |
---|
| 7743 | +struct intel_dbuf_state * |
---|
| 7744 | +intel_atomic_get_dbuf_state(struct intel_atomic_state *state) |
---|
9918 | 7745 | { |
---|
9919 | | - u32 cagf; |
---|
| 7746 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
| 7747 | + struct intel_global_state *dbuf_state; |
---|
9920 | 7748 | |
---|
9921 | | - if (INTEL_GEN(dev_priv) >= 9) |
---|
9922 | | - cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT; |
---|
9923 | | - else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) |
---|
9924 | | - cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT; |
---|
9925 | | - else |
---|
9926 | | - cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT; |
---|
| 7749 | + dbuf_state = intel_atomic_get_global_obj_state(state, &dev_priv->dbuf.obj); |
---|
| 7750 | + if (IS_ERR(dbuf_state)) |
---|
| 7751 | + return ERR_CAST(dbuf_state); |
---|
9927 | 7752 | |
---|
9928 | | - return cagf; |
---|
| 7753 | + return to_intel_dbuf_state(dbuf_state); |
---|
| 7754 | +} |
---|
| 7755 | + |
---|
| 7756 | +int intel_dbuf_init(struct drm_i915_private *dev_priv) |
---|
| 7757 | +{ |
---|
| 7758 | + struct intel_dbuf_state *dbuf_state; |
---|
| 7759 | + |
---|
| 7760 | + dbuf_state = kzalloc(sizeof(*dbuf_state), GFP_KERNEL); |
---|
| 7761 | + if (!dbuf_state) |
---|
| 7762 | + return -ENOMEM; |
---|
| 7763 | + |
---|
| 7764 | + intel_atomic_global_obj_init(dev_priv, &dev_priv->dbuf.obj, |
---|
| 7765 | + &dbuf_state->base, &intel_dbuf_funcs); |
---|
| 7766 | + |
---|
| 7767 | + return 0; |
---|
| 7768 | +} |
---|
| 7769 | + |
---|
| 7770 | +void intel_dbuf_pre_plane_update(struct intel_atomic_state *state) |
---|
| 7771 | +{ |
---|
| 7772 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
| 7773 | + const struct intel_dbuf_state *new_dbuf_state = |
---|
| 7774 | + intel_atomic_get_new_dbuf_state(state); |
---|
| 7775 | + const struct intel_dbuf_state *old_dbuf_state = |
---|
| 7776 | + intel_atomic_get_old_dbuf_state(state); |
---|
| 7777 | + |
---|
| 7778 | + if (!new_dbuf_state || |
---|
| 7779 | + new_dbuf_state->enabled_slices == old_dbuf_state->enabled_slices) |
---|
| 7780 | + return; |
---|
| 7781 | + |
---|
| 7782 | + WARN_ON(!new_dbuf_state->base.changed); |
---|
| 7783 | + |
---|
| 7784 | + gen9_dbuf_slices_update(dev_priv, |
---|
| 7785 | + old_dbuf_state->enabled_slices | |
---|
| 7786 | + new_dbuf_state->enabled_slices); |
---|
| 7787 | +} |
---|
| 7788 | + |
---|
| 7789 | +void intel_dbuf_post_plane_update(struct intel_atomic_state *state) |
---|
| 7790 | +{ |
---|
| 7791 | + struct drm_i915_private *dev_priv = to_i915(state->base.dev); |
---|
| 7792 | + const struct intel_dbuf_state *new_dbuf_state = |
---|
| 7793 | + intel_atomic_get_new_dbuf_state(state); |
---|
| 7794 | + const struct intel_dbuf_state *old_dbuf_state = |
---|
| 7795 | + intel_atomic_get_old_dbuf_state(state); |
---|
| 7796 | + |
---|
| 7797 | + if (!new_dbuf_state || |
---|
| 7798 | + new_dbuf_state->enabled_slices == old_dbuf_state->enabled_slices) |
---|
| 7799 | + return; |
---|
| 7800 | + |
---|
| 7801 | + WARN_ON(!new_dbuf_state->base.changed); |
---|
| 7802 | + |
---|
| 7803 | + gen9_dbuf_slices_update(dev_priv, |
---|
| 7804 | + new_dbuf_state->enabled_slices); |
---|
9929 | 7805 | } |
---|