xref: /linux/drivers/gpu/drm/i915/intel_clock_gating.c (revision c06b6cde2a1c3bcbb561bd57bb6f34eae9030921)
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 <drm/drm_print.h>
29 #include <drm/intel/intel_gmd_interrupt_regs.h>
30 #include <drm/intel/intel_gmd_misc_regs.h>
31 #include <drm/intel/mchbar_regs.h>
32 
33 #include "display/intel_display_clock_gating.h"
34 #include "display/intel_pch.h"
35 #include "gt/intel_engine_regs.h"
36 #include "gt/intel_gt.h"
37 #include "gt/intel_gt_mcr.h"
38 #include "gt/intel_gt_regs.h"
39 
40 #include "i915_drv.h"
41 #include "i915_reg.h"
42 #include "intel_clock_gating.h"
43 #include "vlv_iosf_sb.h"
44 
45 struct drm_i915_clock_gating_funcs {
46 	void (*init_clock_gating)(struct drm_i915_private *i915);
47 };
48 
49 static void bxt_init_clock_gating(struct drm_i915_private *i915)
50 {
51 	/* WaDisableSDEUnitClockGating:bxt */
52 	intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
53 
54 	/*
55 	 * FIXME:
56 	 * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only.
57 	 */
58 	intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6, 0, GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
59 
60 	intel_display_bxt_init_clock_gating(i915->display);
61 }
62 
63 static void glk_init_clock_gating(struct drm_i915_private *i915)
64 {
65 	intel_display_glk_init_clock_gating(i915->display);
66 }
67 
68 static void ilk_init_clock_gating(struct drm_i915_private *i915)
69 {
70 	intel_uncore_write(&i915->uncore, PCH_3DCGDIS0,
71 			   MARIUNIT_CLOCK_GATE_DISABLE |
72 			   SVSMUNIT_CLOCK_GATE_DISABLE);
73 	intel_uncore_write(&i915->uncore, PCH_3DCGDIS1,
74 			   VFMUNIT_CLOCK_GATE_DISABLE);
75 
76 	intel_display_ilk_init_clock_gating(i915->display);
77 	intel_pch_init_clock_gating(i915->display);
78 }
79 
80 static void gen6_check_mch_setup(struct drm_i915_private *i915)
81 {
82 	u32 tmp;
83 
84 	tmp = intel_uncore_read(&i915->uncore, MCH_SSKPD);
85 	if (REG_FIELD_GET(SSKPD_WM0_MASK_SNB, tmp) != 12)
86 		drm_dbg_kms(&i915->drm,
87 			    "Wrong MCH_SSKPD value: 0x%08x This can cause underruns.\n",
88 			    tmp);
89 }
90 
91 static void gen6_init_clock_gating(struct drm_i915_private *i915)
92 {
93 	intel_display_gen6_init_clock_gating(i915->display);
94 
95 	intel_uncore_write(&i915->uncore, GEN6_UCGCTL1,
96 			   intel_uncore_read(&i915->uncore, GEN6_UCGCTL1) |
97 			   GEN6_BLBUNIT_CLOCK_GATE_DISABLE |
98 			   GEN6_CSUNIT_CLOCK_GATE_DISABLE);
99 
100 	/* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
101 	 * gating disable must be set.  Failure to set it results in
102 	 * flickering pixels due to Z write ordering failures after
103 	 * some amount of runtime in the Mesa "fire" demo, and Unigine
104 	 * Sanctuary and Tropics, and apparently anything else with
105 	 * alpha test or pixel discard.
106 	 *
107 	 * According to the spec, bit 11 (RCCUNIT) must also be set,
108 	 * but we didn't debug actual testcases to find it out.
109 	 *
110 	 * WaDisableRCCUnitClockGating:snb
111 	 * WaDisableRCPBUnitClockGating:snb
112 	 */
113 	intel_uncore_write(&i915->uncore, GEN6_UCGCTL2,
114 			   GEN6_RCPBUNIT_CLOCK_GATE_DISABLE |
115 			   GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
116 
117 	/*
118 	 * According to the spec the following bits should be
119 	 * set in order to enable memory self-refresh and fbc:
120 	 * The bit21 and bit22 of 0x42000
121 	 * The bit21 and bit22 of 0x42004
122 	 * The bit5 and bit7 of 0x42020
123 	 * The bit14 of 0x70180
124 	 * The bit14 of 0x71180
125 	 *
126 	 * WaFbcAsynchFlipDisableFbcQueue:snb
127 	 */
128 	intel_pch_init_clock_gating(i915->display);
129 
130 	gen6_check_mch_setup(i915);
131 }
132 
133 static void gen8_set_l3sqc_credits(struct drm_i915_private *i915,
134 				   int general_prio_credits,
135 				   int high_prio_credits)
136 {
137 	u32 misccpctl;
138 	u32 val;
139 
140 	/* WaTempDisableDOPClkGating:bdw */
141 	misccpctl = intel_uncore_rmw(&i915->uncore, GEN7_MISCCPCTL,
142 				     GEN7_DOP_CLOCK_GATE_ENABLE, 0);
143 
144 	val = intel_gt_mcr_read_any(to_gt(i915), GEN8_L3SQCREG1);
145 	val &= ~L3_PRIO_CREDITS_MASK;
146 	val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits);
147 	val |= L3_HIGH_PRIO_CREDITS(high_prio_credits);
148 	intel_gt_mcr_multicast_write(to_gt(i915), GEN8_L3SQCREG1, val);
149 
150 	/*
151 	 * Wait at least 100 clocks before re-enabling clock gating.
152 	 * See the definition of L3SQCREG1 in BSpec.
153 	 */
154 	intel_gt_mcr_read_any(to_gt(i915), GEN8_L3SQCREG1);
155 	udelay(1);
156 	intel_uncore_write(&i915->uncore, GEN7_MISCCPCTL, misccpctl);
157 }
158 
159 static void dg2_init_clock_gating(struct drm_i915_private *i915)
160 {
161 	/* Wa_22010954014:dg2 */
162 	intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0,
163 			 SGSI_SIDECLK_DIS);
164 }
165 
166 static void cfl_init_clock_gating(struct drm_i915_private *i915)
167 {
168 	intel_pch_init_clock_gating(i915->display);
169 
170 	/* WAC6entrylatency:cfl */
171 	intel_uncore_rmw(&i915->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN);
172 
173 	intel_display_cfl_init_clock_gating(i915->display);
174 }
175 
176 static void kbl_init_clock_gating(struct drm_i915_private *i915)
177 {
178 	/* WAC6entrylatency:kbl */
179 	intel_uncore_rmw(&i915->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN);
180 
181 	/* WaDisableSDEUnitClockGating:kbl */
182 	if (IS_KABYLAKE(i915) && IS_GRAPHICS_STEP(i915, 0, STEP_C0))
183 		intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6,
184 				 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
185 
186 	/* WaDisableGamClockGating:kbl */
187 	if (IS_KABYLAKE(i915) && IS_GRAPHICS_STEP(i915, 0, STEP_C0))
188 		intel_uncore_rmw(&i915->uncore, GEN6_UCGCTL1,
189 				 0, GEN6_GAMUNIT_CLOCK_GATE_DISABLE);
190 
191 	intel_display_kbl_init_clock_gating(i915->display);
192 }
193 
194 static void skl_init_clock_gating(struct drm_i915_private *i915)
195 {
196 	/* WaDisableDopClockGating:skl */
197 	intel_uncore_rmw(&i915->uncore, GEN7_MISCCPCTL,
198 			 GEN7_DOP_CLOCK_GATE_ENABLE, 0);
199 
200 	/* WAC6entrylatency:skl */
201 	intel_uncore_rmw(&i915->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN);
202 
203 	intel_display_skl_init_clock_gating(i915->display);
204 }
205 
206 static void bdw_init_clock_gating(struct drm_i915_private *i915)
207 {
208 	intel_display_bdw_clock_gating_disable_fbcq(i915->display);
209 
210 	/* WaSwitchSolVfFArbitrationPriority:bdw */
211 	intel_uncore_rmw(&i915->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL);
212 
213 	intel_display_bdw_clock_gating_vblank_in_srd(i915->display);
214 
215 	/* WaVSRefCountFullforceMissDisable:bdw */
216 	/* WaDSRefCountFullforceMissDisable:bdw */
217 	intel_uncore_rmw(&i915->uncore, GEN7_FF_THREAD_MODE,
218 			 GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME, 0);
219 
220 	intel_uncore_write(&i915->uncore, RING_PSMI_CTL(RENDER_RING_BASE),
221 			   REG_MASKED_FIELD_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
222 
223 	/* WaDisableSDEUnitClockGating:bdw */
224 	intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
225 
226 	/* WaProgramL3SqcReg1Default:bdw */
227 	gen8_set_l3sqc_credits(i915, 30, 2);
228 
229 	intel_display_bdw_clock_gating_kvm_notif(i915->display);
230 
231 	intel_pch_init_clock_gating(i915->display);
232 
233 	/* WaDisableDopClockGating:bdw
234 	 *
235 	 * Also see the CHICKEN2 write in bdw_init_workarounds() to disable DOP
236 	 * clock gating.
237 	 */
238 	intel_uncore_rmw(&i915->uncore, GEN6_UCGCTL1, 0, GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE);
239 }
240 
241 static void hsw_init_clock_gating(struct drm_i915_private *i915)
242 {
243 	intel_display_hsw_init_clock_gating(i915->display);
244 
245 	/* This is required by WaCatErrorRejectionIssue:hsw */
246 	intel_uncore_rmw(&i915->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
247 			 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
248 
249 	/* WaSwitchSolVfFArbitrationPriority:hsw */
250 	intel_uncore_rmw(&i915->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL);
251 
252 	intel_pch_init_clock_gating(i915->display);
253 }
254 
255 static void ivb_init_clock_gating(struct drm_i915_private *i915)
256 {
257 	struct intel_display *display = i915->display;
258 
259 	intel_display_ivb_init_clock_gating(display);
260 
261 	/* WaDisableBackToBackFlipFix:ivb */
262 	intel_uncore_write(&i915->uncore, IVB_CHICKEN3,
263 			   CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
264 			   CHICKEN3_DGMG_DONE_FIX_DISABLE);
265 
266 	if (INTEL_INFO(i915)->gt == 1)
267 		intel_uncore_write(&i915->uncore, GEN7_ROW_CHICKEN2,
268 				   REG_MASKED_FIELD_ENABLE(DOP_CLOCK_GATING_DISABLE));
269 	else {
270 		/* must write both registers */
271 		intel_uncore_write(&i915->uncore, GEN7_ROW_CHICKEN2,
272 				   REG_MASKED_FIELD_ENABLE(DOP_CLOCK_GATING_DISABLE));
273 		intel_uncore_write(&i915->uncore, GEN7_ROW_CHICKEN2_GT2,
274 				   REG_MASKED_FIELD_ENABLE(DOP_CLOCK_GATING_DISABLE));
275 	}
276 
277 	/*
278 	 * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
279 	 * This implements the WaDisableRCZUnitClockGating:ivb workaround.
280 	 */
281 	intel_uncore_write(&i915->uncore, GEN6_UCGCTL2,
282 			   GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
283 
284 	/* This is required by WaCatErrorRejectionIssue:ivb */
285 	intel_uncore_rmw(&i915->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
286 			 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
287 
288 	intel_display_disable_trickle_feed(display);
289 
290 	intel_uncore_rmw(&i915->uncore, GEN6_MBCUNIT_SNPCR, GEN6_MBC_SNPCR_MASK,
291 			 GEN6_MBC_SNPCR_MED);
292 
293 	intel_pch_init_clock_gating(display);
294 
295 	gen6_check_mch_setup(i915);
296 }
297 
298 static void vlv_init_clock_gating(struct drm_i915_private *i915)
299 {
300 	/* WaDisableBackToBackFlipFix:vlv */
301 	intel_uncore_write(&i915->uncore, IVB_CHICKEN3,
302 			   CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
303 			   CHICKEN3_DGMG_DONE_FIX_DISABLE);
304 
305 	/* WaDisableDopClockGating:vlv */
306 	intel_uncore_write(&i915->uncore, GEN7_ROW_CHICKEN2,
307 			   REG_MASKED_FIELD_ENABLE(DOP_CLOCK_GATING_DISABLE));
308 
309 	/* This is required by WaCatErrorRejectionIssue:vlv */
310 	intel_uncore_rmw(&i915->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
311 			 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
312 
313 	/*
314 	 * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
315 	 * This implements the WaDisableRCZUnitClockGating:vlv workaround.
316 	 */
317 	intel_uncore_write(&i915->uncore, GEN6_UCGCTL2,
318 			   GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
319 
320 	/* WaDisableL3Bank2xClockGate:vlv
321 	 * Disabling L3 clock gating- MMIO 940c[25] = 1
322 	 * Set bit 25, to disable L3_BANK_2x_CLK_GATING */
323 	intel_uncore_rmw(&i915->uncore, GEN7_UCGCTL4, 0, GEN7_L3BANK2X_CLOCK_GATE_DISABLE);
324 
325 	/*
326 	 * WaDisableVLVClockGating_VBIIssue:vlv
327 	 * Disable clock gating on th GCFG unit to prevent a delay
328 	 * in the reporting of vblank events.
329 	 */
330 	intel_uncore_write(&i915->uncore, VLV_GUNIT_CLOCK_GATE, GCFG_DIS);
331 }
332 
333 static void chv_init_clock_gating(struct drm_i915_private *i915)
334 {
335 	/* WaVSRefCountFullforceMissDisable:chv */
336 	/* WaDSRefCountFullforceMissDisable:chv */
337 	intel_uncore_rmw(&i915->uncore, GEN7_FF_THREAD_MODE,
338 			 GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME, 0);
339 
340 	/* WaDisableSemaphoreAndSyncFlipWait:chv */
341 	intel_uncore_write(&i915->uncore, RING_PSMI_CTL(RENDER_RING_BASE),
342 			   REG_MASKED_FIELD_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE));
343 
344 	/* WaDisableCSUnitClockGating:chv */
345 	intel_uncore_rmw(&i915->uncore, GEN6_UCGCTL1, 0, GEN6_CSUNIT_CLOCK_GATE_DISABLE);
346 
347 	/* WaDisableSDEUnitClockGating:chv */
348 	intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
349 
350 	/*
351 	 * WaProgramL3SqcReg1Default:chv
352 	 * See gfxspecs/Related Documents/Performance Guide/
353 	 * LSQC Setting Recommendations.
354 	 */
355 	gen8_set_l3sqc_credits(i915, 38, 2);
356 }
357 
358 static void g4x_init_clock_gating(struct drm_i915_private *i915)
359 {
360 	intel_uncore_write(&i915->uncore, RENCLK_GATE_D1, 0);
361 	intel_uncore_write(&i915->uncore, RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
362 			   GS_UNIT_CLOCK_GATE_DISABLE |
363 			   CL_UNIT_CLOCK_GATE_DISABLE);
364 	intel_uncore_write(&i915->uncore, RAMCLK_GATE_D, 0);
365 	intel_display_g4x_init_clock_gating(i915->display);
366 }
367 
368 static void i965gm_init_clock_gating(struct drm_i915_private *i915)
369 {
370 	struct intel_uncore *uncore = &i915->uncore;
371 
372 	intel_uncore_write(uncore, RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
373 	intel_uncore_write(uncore, RENCLK_GATE_D2, 0);
374 	intel_display_i965gm_init_clock_gating(i915->display);
375 	intel_uncore_write(uncore, RAMCLK_GATE_D, 0);
376 	intel_uncore_write16(uncore, DEUC, 0);
377 	intel_uncore_write(uncore,
378 			   MI_ARB_STATE,
379 			   REG_MASKED_FIELD_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
380 }
381 
382 static void i965g_init_clock_gating(struct drm_i915_private *i915)
383 {
384 	intel_uncore_write(&i915->uncore, RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
385 			   I965_RCC_CLOCK_GATE_DISABLE |
386 			   I965_RCPB_CLOCK_GATE_DISABLE |
387 			   I965_ISC_CLOCK_GATE_DISABLE |
388 			   I965_FBC_CLOCK_GATE_DISABLE);
389 	intel_uncore_write(&i915->uncore, RENCLK_GATE_D2, 0);
390 	intel_uncore_write(&i915->uncore, MI_ARB_STATE,
391 			   REG_MASKED_FIELD_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
392 }
393 
394 static void gen3_init_clock_gating(struct drm_i915_private *i915)
395 {
396 	u32 dstate = intel_uncore_read(&i915->uncore, D_STATE);
397 
398 	dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
399 		DSTATE_DOT_CLOCK_GATING;
400 	intel_uncore_write(&i915->uncore, D_STATE, dstate);
401 
402 	if (IS_PINEVIEW(i915))
403 		intel_uncore_write(&i915->uncore, ECOSKPD(RENDER_RING_BASE),
404 				   REG_MASKED_FIELD_ENABLE(ECO_GATING_CX_ONLY));
405 
406 	/* IIR "flip pending" means done if this bit is set */
407 	intel_uncore_write(&i915->uncore, ECOSKPD(RENDER_RING_BASE),
408 			   REG_MASKED_FIELD_DISABLE(ECO_FLIP_DONE));
409 
410 	/* interrupts should cause a wake up from C3 */
411 	intel_uncore_write(&i915->uncore, INSTPM, REG_MASKED_FIELD_ENABLE(INSTPM_AGPBUSY_INT_EN));
412 
413 	/* On GEN3 we really need to make sure the ARB C3 LP bit is set */
414 	intel_uncore_write(&i915->uncore, MI_ARB_STATE,
415 			   REG_MASKED_FIELD_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE));
416 
417 	intel_uncore_write(&i915->uncore, MI_ARB_STATE,
418 			   REG_MASKED_FIELD_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
419 }
420 
421 static void i85x_init_clock_gating(struct drm_i915_private *i915)
422 {
423 	intel_uncore_write(&i915->uncore, RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
424 
425 	/* interrupts should cause a wake up from C3 */
426 	intel_uncore_write(&i915->uncore, MI_STATE, REG_MASKED_FIELD_ENABLE(MI_AGPBUSY_INT_EN) |
427 			   REG_MASKED_FIELD_DISABLE(MI_AGPBUSY_830_MODE));
428 
429 	intel_uncore_write(&i915->uncore, MEM_MODE,
430 			   REG_MASKED_FIELD_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE));
431 
432 	/*
433 	 * Have FBC ignore 3D activity since we use software
434 	 * render tracking, and otherwise a pure 3D workload
435 	 * (even if it just renders a single frame and then does
436 	 * absolutely nothing) would not allow FBC to recompress
437 	 * until a 2D blit occurs.
438 	 */
439 	intel_uncore_write(&i915->uncore, SCPD0,
440 			   REG_MASKED_FIELD_ENABLE(SCPD_FBC_IGNORE_3D));
441 }
442 
443 static void i830_init_clock_gating(struct drm_i915_private *i915)
444 {
445 	intel_uncore_write(&i915->uncore, MEM_MODE,
446 			   REG_MASKED_FIELD_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) |
447 			   REG_MASKED_FIELD_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE));
448 }
449 
450 void intel_clock_gating_init(struct drm_device *drm)
451 {
452 	struct drm_i915_private *i915 = to_i915(drm);
453 
454 	i915->clock_gating_funcs->init_clock_gating(i915);
455 }
456 
457 static void nop_init_clock_gating(struct drm_i915_private *i915)
458 {
459 	drm_dbg_kms(&i915->drm,
460 		    "No clock gating settings or workarounds applied.\n");
461 }
462 
463 #define CG_FUNCS(platform)						\
464 static const struct drm_i915_clock_gating_funcs platform##_clock_gating_funcs = { \
465 	.init_clock_gating = platform##_init_clock_gating,		\
466 }
467 
468 CG_FUNCS(dg2);
469 CG_FUNCS(cfl);
470 CG_FUNCS(skl);
471 CG_FUNCS(kbl);
472 CG_FUNCS(bxt);
473 CG_FUNCS(glk);
474 CG_FUNCS(bdw);
475 CG_FUNCS(chv);
476 CG_FUNCS(hsw);
477 CG_FUNCS(ivb);
478 CG_FUNCS(vlv);
479 CG_FUNCS(gen6);
480 CG_FUNCS(ilk);
481 CG_FUNCS(g4x);
482 CG_FUNCS(i965gm);
483 CG_FUNCS(i965g);
484 CG_FUNCS(gen3);
485 CG_FUNCS(i85x);
486 CG_FUNCS(i830);
487 CG_FUNCS(nop);
488 #undef CG_FUNCS
489 
490 /**
491  * intel_clock_gating_hooks_init - setup the clock gating hooks
492  * @drm: drm device
493  *
494  * Setup the hooks that configure which clocks of a given platform can be
495  * gated and also apply various GT and display specific workarounds for these
496  * platforms. Note that some GT specific workarounds are applied separately
497  * when GPU contexts or batchbuffers start their execution.
498  */
499 void intel_clock_gating_hooks_init(struct drm_device *drm)
500 {
501 	struct drm_i915_private *i915 = to_i915(drm);
502 
503 	if (IS_DG2(i915))
504 		i915->clock_gating_funcs = &dg2_clock_gating_funcs;
505 	else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915))
506 		i915->clock_gating_funcs = &cfl_clock_gating_funcs;
507 	else if (IS_SKYLAKE(i915))
508 		i915->clock_gating_funcs = &skl_clock_gating_funcs;
509 	else if (IS_KABYLAKE(i915))
510 		i915->clock_gating_funcs = &kbl_clock_gating_funcs;
511 	else if (IS_BROXTON(i915))
512 		i915->clock_gating_funcs = &bxt_clock_gating_funcs;
513 	else if (IS_GEMINILAKE(i915))
514 		i915->clock_gating_funcs = &glk_clock_gating_funcs;
515 	else if (IS_BROADWELL(i915))
516 		i915->clock_gating_funcs = &bdw_clock_gating_funcs;
517 	else if (IS_CHERRYVIEW(i915))
518 		i915->clock_gating_funcs = &chv_clock_gating_funcs;
519 	else if (IS_HASWELL(i915))
520 		i915->clock_gating_funcs = &hsw_clock_gating_funcs;
521 	else if (IS_IVYBRIDGE(i915))
522 		i915->clock_gating_funcs = &ivb_clock_gating_funcs;
523 	else if (IS_VALLEYVIEW(i915))
524 		i915->clock_gating_funcs = &vlv_clock_gating_funcs;
525 	else if (GRAPHICS_VER(i915) == 6)
526 		i915->clock_gating_funcs = &gen6_clock_gating_funcs;
527 	else if (GRAPHICS_VER(i915) == 5)
528 		i915->clock_gating_funcs = &ilk_clock_gating_funcs;
529 	else if (IS_G4X(i915))
530 		i915->clock_gating_funcs = &g4x_clock_gating_funcs;
531 	else if (IS_I965GM(i915))
532 		i915->clock_gating_funcs = &i965gm_clock_gating_funcs;
533 	else if (IS_I965G(i915))
534 		i915->clock_gating_funcs = &i965g_clock_gating_funcs;
535 	else if (GRAPHICS_VER(i915) == 3)
536 		i915->clock_gating_funcs = &gen3_clock_gating_funcs;
537 	else if (IS_I85X(i915) || IS_I865G(i915))
538 		i915->clock_gating_funcs = &i85x_clock_gating_funcs;
539 	else if (GRAPHICS_VER(i915) == 2)
540 		i915->clock_gating_funcs = &i830_clock_gating_funcs;
541 	else
542 		i915->clock_gating_funcs = &nop_clock_gating_funcs;
543 }
544