Merge tag 'drm-intel-next-2023-03-07' of git://anongit.freedesktop.org/drm/drm-intel...
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / intel_pm.c
1 /*
2  * Copyright © 2012 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Eugeni Dodonov <eugeni.dodonov@intel.com>
25  *
26  */
27
28 #include "display/intel_de.h"
29 #include "display/intel_display.h"
30 #include "display/intel_display_trace.h"
31 #include "display/skl_watermark.h"
32
33 #include "gt/intel_engine_regs.h"
34 #include "gt/intel_gt.h"
35 #include "gt/intel_gt_mcr.h"
36 #include "gt/intel_gt_regs.h"
37
38 #include "i915_drv.h"
39 #include "intel_mchbar_regs.h"
40 #include "intel_pm.h"
41 #include "vlv_sideband.h"
42
43 struct drm_i915_clock_gating_funcs {
44         void (*init_clock_gating)(struct drm_i915_private *i915);
45 };
46
47 static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
48 {
49         if (HAS_LLC(dev_priv)) {
50                 /*
51                  * WaCompressedResourceDisplayNewHashMode:skl,kbl
52                  * Display WA #0390: skl,kbl
53                  *
54                  * Must match Sampler, Pixel Back End, and Media. See
55                  * WaCompressedResourceSamplerPbeMediaNewHashMode.
56                  */
57                 intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, SKL_DE_COMPRESSED_HASH_MODE);
58         }
59
60         /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
61         intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, SKL_EDP_PSR_FIX_RDWRAP);
62
63         /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */
64         intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, 0, MASK_WAKEMEM);
65
66         /*
67          * WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl
68          * Display WA #0859: skl,bxt,kbl,glk,cfl
69          */
70         intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_MEMORY_WAKE);
71 }
72
73 static void bxt_init_clock_gating(struct drm_i915_private *dev_priv)
74 {
75         gen9_init_clock_gating(dev_priv);
76
77         /* WaDisableSDEUnitClockGating:bxt */
78         intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
79
80         /*
81          * FIXME:
82          * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only.
83          */
84         intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
85
86         /*
87          * Wa: Backlight PWM may stop in the asserted state, causing backlight
88          * to stay fully on.
89          */
90         intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_0, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_0) |
91                    PWM1_GATING_DIS | PWM2_GATING_DIS);
92
93         /*
94          * Lower the display internal timeout.
95          * This is needed to avoid any hard hangs when DSI port PLL
96          * is off and a MMIO access is attempted by any privilege
97          * application, using batch buffers or any other means.
98          */
99         intel_uncore_write(&dev_priv->uncore, RM_TIMEOUT, MMIO_TIMEOUT_US(950));
100
101         /*
102          * WaFbcTurnOffFbcWatermark:bxt
103          * Display WA #0562: bxt
104          */
105         intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS);
106
107         /*
108          * WaFbcHighMemBwCorruptionAvoidance:bxt
109          * Display WA #0883: bxt
110          */
111         intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_DISABLE_DUMMY0);
112 }
113
114 static void glk_init_clock_gating(struct drm_i915_private *dev_priv)
115 {
116         gen9_init_clock_gating(dev_priv);
117
118         /*
119          * WaDisablePWMClockGating:glk
120          * Backlight PWM may stop in the asserted state, causing backlight
121          * to stay fully on.
122          */
123         intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_0, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_0) |
124                    PWM1_GATING_DIS | PWM2_GATING_DIS);
125 }
126
127 static void ibx_init_clock_gating(struct drm_i915_private *dev_priv)
128 {
129         /*
130          * On Ibex Peak and Cougar Point, we need to disable clock
131          * gating for the panel power sequencer or it will fail to
132          * start up when no ports are active.
133          */
134         intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
135 }
136
137 static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv)
138 {
139         enum pipe pipe;
140
141         for_each_pipe(dev_priv, pipe) {
142                 intel_uncore_rmw(&dev_priv->uncore, DSPCNTR(pipe), 0, DISP_TRICKLE_FEED_DISABLE);
143
144                 intel_uncore_rmw(&dev_priv->uncore, DSPSURF(pipe), 0, 0);
145                 intel_uncore_posting_read(&dev_priv->uncore, DSPSURF(pipe));
146         }
147 }
148
149 static void ilk_init_clock_gating(struct drm_i915_private *dev_priv)
150 {
151         u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE;
152
153         /*
154          * Required for FBC
155          * WaFbcDisableDpfcClockGating:ilk
156          */
157         dspclk_gate |= ILK_DPFCRUNIT_CLOCK_GATE_DISABLE |
158                    ILK_DPFCUNIT_CLOCK_GATE_DISABLE |
159                    ILK_DPFDUNIT_CLOCK_GATE_ENABLE;
160
161         intel_uncore_write(&dev_priv->uncore, PCH_3DCGDIS0,
162                    MARIUNIT_CLOCK_GATE_DISABLE |
163                    SVSMUNIT_CLOCK_GATE_DISABLE);
164         intel_uncore_write(&dev_priv->uncore, PCH_3DCGDIS1,
165                    VFMUNIT_CLOCK_GATE_DISABLE);
166
167         /*
168          * According to the spec the following bits should be set in
169          * order to enable memory self-refresh
170          * The bit 22/21 of 0x42004
171          * The bit 5 of 0x42020
172          * The bit 15 of 0x45000
173          */
174         intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2,
175                    (intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) |
176                     ILK_DPARB_GATE | ILK_VSDPFD_FULL));
177         dspclk_gate |= ILK_DPARBUNIT_CLOCK_GATE_ENABLE;
178         intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL,
179                    (intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) |
180                     DISP_FBC_WM_DIS));
181
182         /*
183          * Based on the document from hardware guys the following bits
184          * should be set unconditionally in order to enable FBC.
185          * The bit 22 of 0x42000
186          * The bit 22 of 0x42004
187          * The bit 7,8,9 of 0x42020.
188          */
189         if (IS_IRONLAKE_M(dev_priv)) {
190                 /* WaFbcAsynchFlipDisableFbcQueue:ilk */
191                 intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS);
192                 intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_DPARB_GATE);
193         }
194
195         intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, dspclk_gate);
196
197         intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT);
198
199         g4x_disable_trickle_feed(dev_priv);
200
201         ibx_init_clock_gating(dev_priv);
202 }
203
204 static void cpt_init_clock_gating(struct drm_i915_private *dev_priv)
205 {
206         enum pipe pipe;
207         u32 val;
208
209         /*
210          * On Ibex Peak and Cougar Point, we need to disable clock
211          * gating for the panel power sequencer or it will fail to
212          * start up when no ports are active.
213          */
214         intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE |
215                    PCH_DPLUNIT_CLOCK_GATE_DISABLE |
216                    PCH_CPUNIT_CLOCK_GATE_DISABLE);
217         intel_uncore_rmw(&dev_priv->uncore, SOUTH_CHICKEN2, 0, DPLS_EDP_PPS_FIX_DIS);
218         /* The below fixes the weird display corruption, a few pixels shifted
219          * downward, on (only) LVDS of some HP laptops with IVY.
220          */
221         for_each_pipe(dev_priv, pipe) {
222                 val = intel_uncore_read(&dev_priv->uncore, TRANS_CHICKEN2(pipe));
223                 val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
224                 val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED;
225                 if (dev_priv->display.vbt.fdi_rx_polarity_inverted)
226                         val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED;
227                 val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER;
228                 val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH;
229                 intel_uncore_write(&dev_priv->uncore, TRANS_CHICKEN2(pipe), val);
230         }
231         /* WADP0ClockGatingDisable */
232         for_each_pipe(dev_priv, pipe) {
233                 intel_uncore_write(&dev_priv->uncore, TRANS_CHICKEN1(pipe),
234                            TRANS_CHICKEN1_DP0UNIT_GC_DISABLE);
235         }
236 }
237
238 static void gen6_check_mch_setup(struct drm_i915_private *dev_priv)
239 {
240         u32 tmp;
241
242         tmp = intel_uncore_read(&dev_priv->uncore, MCH_SSKPD);
243         if (REG_FIELD_GET(SSKPD_WM0_MASK_SNB, tmp) != 12)
244                 drm_dbg_kms(&dev_priv->drm,
245                             "Wrong MCH_SSKPD value: 0x%08x This can cause underruns.\n",
246                             tmp);
247 }
248
249 static void gen6_init_clock_gating(struct drm_i915_private *dev_priv)
250 {
251         u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE;
252
253         intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, dspclk_gate);
254
255         intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT);
256
257         intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL1,
258                    intel_uncore_read(&dev_priv->uncore, GEN6_UCGCTL1) |
259                    GEN6_BLBUNIT_CLOCK_GATE_DISABLE |
260                    GEN6_CSUNIT_CLOCK_GATE_DISABLE);
261
262         /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
263          * gating disable must be set.  Failure to set it results in
264          * flickering pixels due to Z write ordering failures after
265          * some amount of runtime in the Mesa "fire" demo, and Unigine
266          * Sanctuary and Tropics, and apparently anything else with
267          * alpha test or pixel discard.
268          *
269          * According to the spec, bit 11 (RCCUNIT) must also be set,
270          * but we didn't debug actual testcases to find it out.
271          *
272          * WaDisableRCCUnitClockGating:snb
273          * WaDisableRCPBUnitClockGating:snb
274          */
275         intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2,
276                    GEN6_RCPBUNIT_CLOCK_GATE_DISABLE |
277                    GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
278
279         /*
280          * According to the spec the following bits should be
281          * set in order to enable memory self-refresh and fbc:
282          * The bit21 and bit22 of 0x42000
283          * The bit21 and bit22 of 0x42004
284          * The bit5 and bit7 of 0x42020
285          * The bit14 of 0x70180
286          * The bit14 of 0x71180
287          *
288          * WaFbcAsynchFlipDisableFbcQueue:snb
289          */
290         intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1,
291                    intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1) |
292                    ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS);
293         intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2,
294                    intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) |
295                    ILK_DPARB_GATE | ILK_VSDPFD_FULL);
296         intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D,
297                    intel_uncore_read(&dev_priv->uncore, ILK_DSPCLK_GATE_D) |
298                    ILK_DPARBUNIT_CLOCK_GATE_ENABLE  |
299                    ILK_DPFDUNIT_CLOCK_GATE_ENABLE);
300
301         g4x_disable_trickle_feed(dev_priv);
302
303         cpt_init_clock_gating(dev_priv);
304
305         gen6_check_mch_setup(dev_priv);
306 }
307
308 static void lpt_init_clock_gating(struct drm_i915_private *dev_priv)
309 {
310         /*
311          * TODO: this bit should only be enabled when really needed, then
312          * disabled when not needed anymore in order to save power.
313          */
314         if (HAS_PCH_LPT_LP(dev_priv))
315                 intel_uncore_rmw(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D,
316                                  0, PCH_LP_PARTITION_LEVEL_DISABLE);
317
318         /* WADPOClockGatingDisable:hsw */
319         intel_uncore_rmw(&dev_priv->uncore, TRANS_CHICKEN1(PIPE_A),
320                          0, TRANS_CHICKEN1_DP0UNIT_GC_DISABLE);
321 }
322
323 static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv,
324                                    int general_prio_credits,
325                                    int high_prio_credits)
326 {
327         u32 misccpctl;
328         u32 val;
329
330         /* WaTempDisableDOPClkGating:bdw */
331         misccpctl = intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL,
332                                      GEN7_DOP_CLOCK_GATE_ENABLE, 0);
333
334         val = intel_gt_mcr_read_any(to_gt(dev_priv), GEN8_L3SQCREG1);
335         val &= ~L3_PRIO_CREDITS_MASK;
336         val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits);
337         val |= L3_HIGH_PRIO_CREDITS(high_prio_credits);
338         intel_gt_mcr_multicast_write(to_gt(dev_priv), GEN8_L3SQCREG1, val);
339
340         /*
341          * Wait at least 100 clocks before re-enabling clock gating.
342          * See the definition of L3SQCREG1 in BSpec.
343          */
344         intel_gt_mcr_read_any(to_gt(dev_priv), GEN8_L3SQCREG1);
345         udelay(1);
346         intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl);
347 }
348
349 static void icl_init_clock_gating(struct drm_i915_private *dev_priv)
350 {
351         /* Wa_1409120013:icl,ehl */
352         intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A),
353                            DPFC_CHICKEN_COMP_DUMMY_PIXEL);
354
355         /*Wa_14010594013:icl, ehl */
356         intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1,
357                          0, ICL_DELAY_PMRSP);
358 }
359
360 static void gen12lp_init_clock_gating(struct drm_i915_private *dev_priv)
361 {
362         /* Wa_1409120013 */
363         if (DISPLAY_VER(dev_priv) == 12)
364                 intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A),
365                                    DPFC_CHICKEN_COMP_DUMMY_PIXEL);
366
367         /* Wa_14013723622:tgl,rkl,dg1,adl-s */
368         if (DISPLAY_VER(dev_priv) == 12)
369                 intel_uncore_rmw(&dev_priv->uncore, CLKREQ_POLICY,
370                                  CLKREQ_POLICY_MEM_UP_OVRD, 0);
371 }
372
373 static void adlp_init_clock_gating(struct drm_i915_private *dev_priv)
374 {
375         gen12lp_init_clock_gating(dev_priv);
376
377         /* Wa_22011091694:adlp */
378         intel_de_rmw(dev_priv, GEN9_CLKGATE_DIS_5, 0, DPCE_GATING_DIS);
379
380         /* Bspec/49189 Initialize Sequence */
381         intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, DDI_CLOCK_REG_ACCESS, 0);
382 }
383
384 static void xehpsdv_init_clock_gating(struct drm_i915_private *dev_priv)
385 {
386         /* Wa_22010146351:xehpsdv */
387         if (IS_XEHPSDV_GRAPHICS_STEP(dev_priv, STEP_A0, STEP_B0))
388                 intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGR_DIS);
389 }
390
391 static void dg2_init_clock_gating(struct drm_i915_private *i915)
392 {
393         /* Wa_22010954014:dg2 */
394         intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0,
395                          SGSI_SIDECLK_DIS);
396
397         /*
398          * Wa_14010733611:dg2_g10
399          * Wa_22010146351:dg2_g10
400          */
401         if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0))
402                 intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0,
403                                  SGR_DIS | SGGI_DIS);
404 }
405
406 static void pvc_init_clock_gating(struct drm_i915_private *dev_priv)
407 {
408         /* Wa_14012385139:pvc */
409         if (IS_PVC_BD_STEP(dev_priv, STEP_A0, STEP_B0))
410                 intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGR_DIS);
411
412         /* Wa_22010954014:pvc */
413         if (IS_PVC_BD_STEP(dev_priv, STEP_A0, STEP_B0))
414                 intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGSI_SIDECLK_DIS);
415 }
416
417 static void cnp_init_clock_gating(struct drm_i915_private *dev_priv)
418 {
419         if (!HAS_PCH_CNP(dev_priv))
420                 return;
421
422         /* Display WA #1181 WaSouthDisplayDisablePWMCGEGating: cnp */
423         intel_uncore_rmw(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, 0, CNP_PWM_CGE_GATING_DISABLE);
424 }
425
426 static void cfl_init_clock_gating(struct drm_i915_private *dev_priv)
427 {
428         cnp_init_clock_gating(dev_priv);
429         gen9_init_clock_gating(dev_priv);
430
431         /* WAC6entrylatency:cfl */
432         intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN);
433
434         /*
435          * WaFbcTurnOffFbcWatermark:cfl
436          * Display WA #0562: cfl
437          */
438         intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS);
439
440         /*
441          * WaFbcNukeOnHostModify:cfl
442          * Display WA #0873: cfl
443          */
444         intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A),
445                          0, DPFC_NUKE_ON_ANY_MODIFICATION);
446 }
447
448 static void kbl_init_clock_gating(struct drm_i915_private *dev_priv)
449 {
450         gen9_init_clock_gating(dev_priv);
451
452         /* WAC6entrylatency:kbl */
453         intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN);
454
455         /* WaDisableSDEUnitClockGating:kbl */
456         if (IS_KBL_GRAPHICS_STEP(dev_priv, 0, STEP_C0))
457                 intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6,
458                                  0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
459
460         /* WaDisableGamClockGating:kbl */
461         if (IS_KBL_GRAPHICS_STEP(dev_priv, 0, STEP_C0))
462                 intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1,
463                                  0, GEN6_GAMUNIT_CLOCK_GATE_DISABLE);
464
465         /*
466          * WaFbcTurnOffFbcWatermark:kbl
467          * Display WA #0562: kbl
468          */
469         intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS);
470
471         /*
472          * WaFbcNukeOnHostModify:kbl
473          * Display WA #0873: kbl
474          */
475         intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A),
476                          0, DPFC_NUKE_ON_ANY_MODIFICATION);
477 }
478
479 static void skl_init_clock_gating(struct drm_i915_private *dev_priv)
480 {
481         gen9_init_clock_gating(dev_priv);
482
483         /* WaDisableDopClockGating:skl */
484         intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL,
485                          GEN7_DOP_CLOCK_GATE_ENABLE, 0);
486
487         /* WAC6entrylatency:skl */
488         intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN);
489
490         /*
491          * WaFbcTurnOffFbcWatermark:skl
492          * Display WA #0562: skl
493          */
494         intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS);
495
496         /*
497          * WaFbcNukeOnHostModify:skl
498          * Display WA #0873: skl
499          */
500         intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A),
501                          0, DPFC_NUKE_ON_ANY_MODIFICATION);
502
503         /*
504          * WaFbcHighMemBwCorruptionAvoidance:skl
505          * Display WA #0883: skl
506          */
507         intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_DISABLE_DUMMY0);
508 }
509
510 static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
511 {
512         enum pipe pipe;
513
514         /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */
515         intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS);
516
517         /* WaSwitchSolVfFArbitrationPriority:bdw */
518         intel_uncore_rmw(&dev_priv->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL);
519
520         /* WaPsrDPAMaskVBlankInSRD:bdw */
521         intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, DPA_MASK_VBLANK_SRD);
522
523         for_each_pipe(dev_priv, pipe) {
524                 /* WaPsrDPRSUnmaskVBlankInSRD:bdw */
525                 intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe),
526                                  0, BDW_DPRS_MASK_VBLANK_SRD);
527         }
528
529         /* WaVSRefCountFullforceMissDisable:bdw */
530         /* WaDSRefCountFullforceMissDisable:bdw */
531         intel_uncore_rmw(&dev_priv->uncore, GEN7_FF_THREAD_MODE,
532                          GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME, 0);
533
534         intel_uncore_write(&dev_priv->uncore, RING_PSMI_CTL(RENDER_RING_BASE),
535                    _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
536
537         /* WaDisableSDEUnitClockGating:bdw */
538         intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
539
540         /* WaProgramL3SqcReg1Default:bdw */
541         gen8_set_l3sqc_credits(dev_priv, 30, 2);
542
543         /* WaKVMNotificationOnConfigChange:bdw */
544         intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR2_1,
545                          0, KVM_CONFIG_CHANGE_NOTIFICATION_SELECT);
546
547         lpt_init_clock_gating(dev_priv);
548
549         /* WaDisableDopClockGating:bdw
550          *
551          * Also see the CHICKEN2 write in bdw_init_workarounds() to disable DOP
552          * clock gating.
553          */
554         intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1, 0, GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE);
555 }
556
557 static void hsw_init_clock_gating(struct drm_i915_private *dev_priv)
558 {
559         /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */
560         intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS);
561
562         /* This is required by WaCatErrorRejectionIssue:hsw */
563         intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
564                          0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
565
566         /* WaSwitchSolVfFArbitrationPriority:hsw */
567         intel_uncore_rmw(&dev_priv->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL);
568
569         lpt_init_clock_gating(dev_priv);
570 }
571
572 static void ivb_init_clock_gating(struct drm_i915_private *dev_priv)
573 {
574         intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE);
575
576         /* WaFbcAsynchFlipDisableFbcQueue:ivb */
577         intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS);
578
579         /* WaDisableBackToBackFlipFix:ivb */
580         intel_uncore_write(&dev_priv->uncore, IVB_CHICKEN3,
581                    CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
582                    CHICKEN3_DGMG_DONE_FIX_DISABLE);
583
584         if (IS_IVB_GT1(dev_priv))
585                 intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2,
586                            _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
587         else {
588                 /* must write both registers */
589                 intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2,
590                            _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
591                 intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2_GT2,
592                            _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
593         }
594
595         /*
596          * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
597          * This implements the WaDisableRCZUnitClockGating:ivb workaround.
598          */
599         intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2,
600                    GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
601
602         /* This is required by WaCatErrorRejectionIssue:ivb */
603         intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
604                          0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
605
606         g4x_disable_trickle_feed(dev_priv);
607
608         intel_uncore_rmw(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR, GEN6_MBC_SNPCR_MASK,
609                          GEN6_MBC_SNPCR_MED);
610
611         if (!HAS_PCH_NOP(dev_priv))
612                 cpt_init_clock_gating(dev_priv);
613
614         gen6_check_mch_setup(dev_priv);
615 }
616
617 static void vlv_init_clock_gating(struct drm_i915_private *dev_priv)
618 {
619         /* WaDisableBackToBackFlipFix:vlv */
620         intel_uncore_write(&dev_priv->uncore, IVB_CHICKEN3,
621                    CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
622                    CHICKEN3_DGMG_DONE_FIX_DISABLE);
623
624         /* WaDisableDopClockGating:vlv */
625         intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2,
626                    _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
627
628         /* This is required by WaCatErrorRejectionIssue:vlv */
629         intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
630                          0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
631
632         /*
633          * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
634          * This implements the WaDisableRCZUnitClockGating:vlv workaround.
635          */
636         intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2,
637                    GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
638
639         /* WaDisableL3Bank2xClockGate:vlv
640          * Disabling L3 clock gating- MMIO 940c[25] = 1
641          * Set bit 25, to disable L3_BANK_2x_CLK_GATING */
642         intel_uncore_rmw(&dev_priv->uncore, GEN7_UCGCTL4, 0, GEN7_L3BANK2X_CLOCK_GATE_DISABLE);
643
644         /*
645          * WaDisableVLVClockGating_VBIIssue:vlv
646          * Disable clock gating on th GCFG unit to prevent a delay
647          * in the reporting of vblank events.
648          */
649         intel_uncore_write(&dev_priv->uncore, VLV_GUNIT_CLOCK_GATE, GCFG_DIS);
650 }
651
652 static void chv_init_clock_gating(struct drm_i915_private *dev_priv)
653 {
654         /* WaVSRefCountFullforceMissDisable:chv */
655         /* WaDSRefCountFullforceMissDisable:chv */
656         intel_uncore_rmw(&dev_priv->uncore, GEN7_FF_THREAD_MODE,
657                          GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME, 0);
658
659         /* WaDisableSemaphoreAndSyncFlipWait:chv */
660         intel_uncore_write(&dev_priv->uncore, RING_PSMI_CTL(RENDER_RING_BASE),
661                    _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
662
663         /* WaDisableCSUnitClockGating:chv */
664         intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1, 0, GEN6_CSUNIT_CLOCK_GATE_DISABLE);
665
666         /* WaDisableSDEUnitClockGating:chv */
667         intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
668
669         /*
670          * WaProgramL3SqcReg1Default:chv
671          * See gfxspecs/Related Documents/Performance Guide/
672          * LSQC Setting Recommendations.
673          */
674         gen8_set_l3sqc_credits(dev_priv, 38, 2);
675 }
676
677 static void g4x_init_clock_gating(struct drm_i915_private *dev_priv)
678 {
679         u32 dspclk_gate;
680
681         intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, 0);
682         intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
683                    GS_UNIT_CLOCK_GATE_DISABLE |
684                    CL_UNIT_CLOCK_GATE_DISABLE);
685         intel_uncore_write(&dev_priv->uncore, RAMCLK_GATE_D, 0);
686         dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE |
687                 OVRUNIT_CLOCK_GATE_DISABLE |
688                 OVCUNIT_CLOCK_GATE_DISABLE;
689         if (IS_GM45(dev_priv))
690                 dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE;
691         intel_uncore_write(&dev_priv->uncore, DSPCLK_GATE_D(dev_priv), dspclk_gate);
692
693         g4x_disable_trickle_feed(dev_priv);
694 }
695
696 static void i965gm_init_clock_gating(struct drm_i915_private *dev_priv)
697 {
698         struct intel_uncore *uncore = &dev_priv->uncore;
699
700         intel_uncore_write(uncore, RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
701         intel_uncore_write(uncore, RENCLK_GATE_D2, 0);
702         intel_uncore_write(uncore, DSPCLK_GATE_D(dev_priv), 0);
703         intel_uncore_write(uncore, RAMCLK_GATE_D, 0);
704         intel_uncore_write16(uncore, DEUC, 0);
705         intel_uncore_write(uncore,
706                            MI_ARB_STATE,
707                            _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
708 }
709
710 static void i965g_init_clock_gating(struct drm_i915_private *dev_priv)
711 {
712         intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
713                    I965_RCC_CLOCK_GATE_DISABLE |
714                    I965_RCPB_CLOCK_GATE_DISABLE |
715                    I965_ISC_CLOCK_GATE_DISABLE |
716                    I965_FBC_CLOCK_GATE_DISABLE);
717         intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D2, 0);
718         intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE,
719                    _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
720 }
721
722 static void gen3_init_clock_gating(struct drm_i915_private *dev_priv)
723 {
724         u32 dstate = intel_uncore_read(&dev_priv->uncore, D_STATE);
725
726         dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
727                 DSTATE_DOT_CLOCK_GATING;
728         intel_uncore_write(&dev_priv->uncore, D_STATE, dstate);
729
730         if (IS_PINEVIEW(dev_priv))
731                 intel_uncore_write(&dev_priv->uncore, ECOSKPD(RENDER_RING_BASE),
732                                    _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY));
733
734         /* IIR "flip pending" means done if this bit is set */
735         intel_uncore_write(&dev_priv->uncore, ECOSKPD(RENDER_RING_BASE),
736                            _MASKED_BIT_DISABLE(ECO_FLIP_DONE));
737
738         /* interrupts should cause a wake up from C3 */
739         intel_uncore_write(&dev_priv->uncore, INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_INT_EN));
740
741         /* On GEN3 we really need to make sure the ARB C3 LP bit is set */
742         intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE));
743
744         intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE,
745                    _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
746 }
747
748 static void i85x_init_clock_gating(struct drm_i915_private *dev_priv)
749 {
750         intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
751
752         /* interrupts should cause a wake up from C3 */
753         intel_uncore_write(&dev_priv->uncore, MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) |
754                    _MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE));
755
756         intel_uncore_write(&dev_priv->uncore, MEM_MODE,
757                    _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE));
758
759         /*
760          * Have FBC ignore 3D activity since we use software
761          * render tracking, and otherwise a pure 3D workload
762          * (even if it just renders a single frame and then does
763          * abosultely nothing) would not allow FBC to recompress
764          * until a 2D blit occurs.
765          */
766         intel_uncore_write(&dev_priv->uncore, SCPD0,
767                    _MASKED_BIT_ENABLE(SCPD_FBC_IGNORE_3D));
768 }
769
770 static void i830_init_clock_gating(struct drm_i915_private *dev_priv)
771 {
772         intel_uncore_write(&dev_priv->uncore, MEM_MODE,
773                    _MASKED_BIT_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) |
774                    _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE));
775 }
776
777 void intel_init_clock_gating(struct drm_i915_private *dev_priv)
778 {
779         dev_priv->clock_gating_funcs->init_clock_gating(dev_priv);
780 }
781
782 static void nop_init_clock_gating(struct drm_i915_private *dev_priv)
783 {
784         drm_dbg_kms(&dev_priv->drm,
785                     "No clock gating settings or workarounds applied.\n");
786 }
787
788 #define CG_FUNCS(platform)                                              \
789 static const struct drm_i915_clock_gating_funcs platform##_clock_gating_funcs = { \
790         .init_clock_gating = platform##_init_clock_gating,              \
791 }
792
793 CG_FUNCS(pvc);
794 CG_FUNCS(dg2);
795 CG_FUNCS(xehpsdv);
796 CG_FUNCS(adlp);
797 CG_FUNCS(gen12lp);
798 CG_FUNCS(icl);
799 CG_FUNCS(cfl);
800 CG_FUNCS(skl);
801 CG_FUNCS(kbl);
802 CG_FUNCS(bxt);
803 CG_FUNCS(glk);
804 CG_FUNCS(bdw);
805 CG_FUNCS(chv);
806 CG_FUNCS(hsw);
807 CG_FUNCS(ivb);
808 CG_FUNCS(vlv);
809 CG_FUNCS(gen6);
810 CG_FUNCS(ilk);
811 CG_FUNCS(g4x);
812 CG_FUNCS(i965gm);
813 CG_FUNCS(i965g);
814 CG_FUNCS(gen3);
815 CG_FUNCS(i85x);
816 CG_FUNCS(i830);
817 CG_FUNCS(nop);
818 #undef CG_FUNCS
819
820 /**
821  * intel_init_clock_gating_hooks - setup the clock gating hooks
822  * @dev_priv: device private
823  *
824  * Setup the hooks that configure which clocks of a given platform can be
825  * gated and also apply various GT and display specific workarounds for these
826  * platforms. Note that some GT specific workarounds are applied separately
827  * when GPU contexts or batchbuffers start their execution.
828  */
829 void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv)
830 {
831         if (IS_METEORLAKE(dev_priv))
832                 dev_priv->clock_gating_funcs = &nop_clock_gating_funcs;
833         else if (IS_PONTEVECCHIO(dev_priv))
834                 dev_priv->clock_gating_funcs = &pvc_clock_gating_funcs;
835         else if (IS_DG2(dev_priv))
836                 dev_priv->clock_gating_funcs = &dg2_clock_gating_funcs;
837         else if (IS_XEHPSDV(dev_priv))
838                 dev_priv->clock_gating_funcs = &xehpsdv_clock_gating_funcs;
839         else if (IS_ALDERLAKE_P(dev_priv))
840                 dev_priv->clock_gating_funcs = &adlp_clock_gating_funcs;
841         else if (GRAPHICS_VER(dev_priv) == 12)
842                 dev_priv->clock_gating_funcs = &gen12lp_clock_gating_funcs;
843         else if (GRAPHICS_VER(dev_priv) == 11)
844                 dev_priv->clock_gating_funcs = &icl_clock_gating_funcs;
845         else if (IS_COFFEELAKE(dev_priv) || IS_COMETLAKE(dev_priv))
846                 dev_priv->clock_gating_funcs = &cfl_clock_gating_funcs;
847         else if (IS_SKYLAKE(dev_priv))
848                 dev_priv->clock_gating_funcs = &skl_clock_gating_funcs;
849         else if (IS_KABYLAKE(dev_priv))
850                 dev_priv->clock_gating_funcs = &kbl_clock_gating_funcs;
851         else if (IS_BROXTON(dev_priv))
852                 dev_priv->clock_gating_funcs = &bxt_clock_gating_funcs;
853         else if (IS_GEMINILAKE(dev_priv))
854                 dev_priv->clock_gating_funcs = &glk_clock_gating_funcs;
855         else if (IS_BROADWELL(dev_priv))
856                 dev_priv->clock_gating_funcs = &bdw_clock_gating_funcs;
857         else if (IS_CHERRYVIEW(dev_priv))
858                 dev_priv->clock_gating_funcs = &chv_clock_gating_funcs;
859         else if (IS_HASWELL(dev_priv))
860                 dev_priv->clock_gating_funcs = &hsw_clock_gating_funcs;
861         else if (IS_IVYBRIDGE(dev_priv))
862                 dev_priv->clock_gating_funcs = &ivb_clock_gating_funcs;
863         else if (IS_VALLEYVIEW(dev_priv))
864                 dev_priv->clock_gating_funcs = &vlv_clock_gating_funcs;
865         else if (GRAPHICS_VER(dev_priv) == 6)
866                 dev_priv->clock_gating_funcs = &gen6_clock_gating_funcs;
867         else if (GRAPHICS_VER(dev_priv) == 5)
868                 dev_priv->clock_gating_funcs = &ilk_clock_gating_funcs;
869         else if (IS_G4X(dev_priv))
870                 dev_priv->clock_gating_funcs = &g4x_clock_gating_funcs;
871         else if (IS_I965GM(dev_priv))
872                 dev_priv->clock_gating_funcs = &i965gm_clock_gating_funcs;
873         else if (IS_I965G(dev_priv))
874                 dev_priv->clock_gating_funcs = &i965g_clock_gating_funcs;
875         else if (GRAPHICS_VER(dev_priv) == 3)
876                 dev_priv->clock_gating_funcs = &gen3_clock_gating_funcs;
877         else if (IS_I85X(dev_priv) || IS_I865G(dev_priv))
878                 dev_priv->clock_gating_funcs = &i85x_clock_gating_funcs;
879         else if (GRAPHICS_VER(dev_priv) == 2)
880                 dev_priv->clock_gating_funcs = &i830_clock_gating_funcs;
881         else {
882                 MISSING_CASE(INTEL_DEVID(dev_priv));
883                 dev_priv->clock_gating_funcs = &nop_clock_gating_funcs;
884         }
885 }