xref: /linux/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c (revision f82480fafedf622541276d48a3b4fed20ce5d866)
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copyright 2023 Advanced Micro Devices, Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  */
24 
25 #include "reg_helper.h"
26 #include "core_types.h"
27 #include "resource.h"
28 #include "dcn35_dccg.h"
29 #include "dcn20/dcn20_dccg.h"
30 
31 #define TO_DCN_DCCG(dccg)\
32 	container_of(dccg, struct dcn_dccg, base)
33 
34 #define REG(reg) \
35 	(dccg_dcn->regs->reg)
36 
37 #undef FN
38 #define FN(reg_name, field_name) \
39 	dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name
40 
41 #define CTX \
42 	dccg_dcn->base.ctx
43 #include "logger_types.h"
44 #define DC_LOGGER \
45 	dccg->ctx->logger
46 
47 enum symclk_fe_source {
48 	SYMCLK_FE_SYMCLK_A = 0,	// Select functional clock from backend symclk A
49 	SYMCLK_FE_SYMCLK_B,
50 	SYMCLK_FE_SYMCLK_C,
51 	SYMCLK_FE_SYMCLK_D,
52 	SYMCLK_FE_SYMCLK_E,
53 	SYMCLK_FE_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software
54 };
55 
56 enum symclk_be_source {
57 	SYMCLK_BE_PHYCLK = 0,	// Select phy clk when sym_clk_enable = 1
58 	SYMCLK_BE_DPIACLK_810 = 4,
59 	SYMCLK_BE_DPIACLK_162 = 5,
60 	SYMCLK_BE_DPIACLK_540 = 6,
61 	SYMCLK_BE_DPIACLK_270 = 7,
62 	SYMCLK_BE_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software
63 };
64 
65 enum physymclk_source {
66 	PHYSYMCLK_PHYCLK = 0,		// Select symclk as source of clock which is output to PHY through DCIO.
67 	PHYSYMCLK_PHYD18CLK,		// Select phyd18clk as the source of clock which is output to PHY through DCIO.
68 	PHYSYMCLK_PHYD32CLK,		// Select phyd32clk as the source of clock which is output to PHY through DCIO.
69 	PHYSYMCLK_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software
70 };
71 
72 enum dtbclk_source {
73 	DTBCLK_DPREFCLK = 0,		// Selects source for DTBCLK_P# as DPREFCLK (src sel 0 and 1 are same)
74 	DTBCLK_DPREFCLK_0,			// Selects source for DTBCLK_P# as DPREFCLK (src sel 0 and 1 are same)
75 	DTBCLK_DTBCLK0,				// Selects source for DTBCLK_P# as DTBCLK0
76 	DTBCLK_DTBCLK1,				// Selects source for DTBCLK_P# as DTBCLK0
77 	DTBCLK_REFCLK = 0xFF,		// Arbitrary value to pass refclk selection in software
78 };
79 
80 enum dppclk_clock_source {
81 	DPP_REFCLK = 0,				// refclk is selected
82 	DPP_DCCG_DTO,				// Functional clock selected is DTO tuned DPPCLK
83 };
84 
85 enum dp_stream_clk_source {
86 	DP_STREAM_DTBCLK_P0 = 0,	// Selects functional for DP_STREAM_CLK as DTBCLK_P#
87 	DP_STREAM_DTBCLK_P1,
88 	DP_STREAM_DTBCLK_P2,
89 	DP_STREAM_DTBCLK_P3,
90 	DP_STREAM_DTBCLK_P4,
91 	DP_STREAM_DTBCLK_P5,
92 	DP_STREAM_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software
93 };
94 
95 enum hdmi_char_clk {
96 	HDMI_CHAR_PHYAD18CLK = 0,	// Selects functional for hdmi_char_clk as UNIPHYA PHYD18CLK
97 	HDMI_CHAR_PHYBD18CLK,
98 	HDMI_CHAR_PHYCD18CLK,
99 	HDMI_CHAR_PHYDD18CLK,
100 	HDMI_CHAR_PHYED18CLK,
101 	HDMI_CHAR_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software
102 };
103 
104 enum hdmi_stream_clk_source {
105 	HDMI_STREAM_DTBCLK_P0 = 0,	// Selects functional for HDMI_STREAM_CLK as DTBCLK_P#
106 	HDMI_STREAM_DTBCLK_P1,
107 	HDMI_STREAM_DTBCLK_P2,
108 	HDMI_STREAM_DTBCLK_P3,
109 	HDMI_STREAM_DTBCLK_P4,
110 	HDMI_STREAM_DTBCLK_P5,
111 	HDMI_STREAM_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software
112 };
113 
114 enum symclk32_se_clk_source {
115 	SYMCLK32_SE_PHYAD32CLK = 0,	// Selects functional for SYMCLK32 as UNIPHYA PHYD32CLK
116 	SYMCLK32_SE_PHYBD32CLK,
117 	SYMCLK32_SE_PHYCD32CLK,
118 	SYMCLK32_SE_PHYDD32CLK,
119 	SYMCLK32_SE_PHYED32CLK,
120 	SYMCLK32_SE_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software
121 };
122 
123 enum symclk32_le_clk_source {
124 	SYMCLK32_LE_PHYAD32CLK = 0,	// Selects functional for SYMCLK32 as UNIPHYA PHYD32CLK
125 	SYMCLK32_LE_PHYBD32CLK,
126 	SYMCLK32_LE_PHYCD32CLK,
127 	SYMCLK32_LE_PHYDD32CLK,
128 	SYMCLK32_LE_PHYED32CLK,
129 	SYMCLK32_LE_REFCLK = 0xFF,	// Arbitrary value to pass refclk selection in software
130 };
131 
132 enum dsc_clk_source {
133 	DSC_CLK_REF_CLK = 0,			// Ref clock selected for DSC_CLK
134 	DSC_DTO_TUNED_CK_GPU_DISCLK_3,	// DTO divided clock selected as functional clock
135 };
136 
137 
138 static void dccg35_set_dsc_clk_rcg(struct dccg *dccg, int inst, bool allow_rcg)
139 {
140 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
141 
142 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc && allow_rcg)
143 		return;
144 
145 	switch (inst) {
146 	case 0:
147 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1);
148 		break;
149 	case 1:
150 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1);
151 		break;
152 	case 2:
153 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1);
154 		break;
155 	case 3:
156 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1);
157 		break;
158 	default:
159 		BREAK_TO_DEBUGGER();
160 		return;
161 	}
162 
163 	/* Wait for clock to ramp */
164 	if (!allow_rcg)
165 		udelay(10);
166 }
167 
168 static void dccg35_set_symclk32_se_rcg(
169 	struct dccg *dccg,
170 	int inst,
171 	bool enable)
172 {
173 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
174 
175 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)
176 		return;
177 
178 	/* SYMCLK32_ROOT_SE#_GATE_DISABLE will clock gate in DCCG */
179 	/* SYMCLK32_SE#_GATE_DISABLE will clock gate in HPO only */
180 	switch (inst) {
181 	case 0:
182 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
183 				   SYMCLK32_SE0_GATE_DISABLE, enable ? 0 : 1,
184 				   SYMCLK32_ROOT_SE0_GATE_DISABLE, enable ? 0 : 1);
185 		break;
186 	case 1:
187 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
188 				   SYMCLK32_SE1_GATE_DISABLE, enable ? 0 : 1,
189 				   SYMCLK32_ROOT_SE1_GATE_DISABLE, enable ? 0 : 1);
190 		break;
191 	case 2:
192 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
193 				   SYMCLK32_SE2_GATE_DISABLE, enable ? 0 : 1,
194 				   SYMCLK32_ROOT_SE2_GATE_DISABLE, enable ? 0 : 1);
195 		break;
196 	case 3:
197 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
198 				   SYMCLK32_SE3_GATE_DISABLE, enable ? 0 : 1,
199 				   SYMCLK32_ROOT_SE3_GATE_DISABLE, enable ? 0 : 1);
200 		break;
201 	default:
202 		BREAK_TO_DEBUGGER();
203 		return;
204 	}
205 }
206 
207 static void dccg35_set_symclk32_le_rcg(
208 	struct dccg *dccg,
209 	int inst,
210 	bool enable)
211 {
212 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
213 
214 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le && enable)
215 		return;
216 
217 	switch (inst) {
218 	case 0:
219 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
220 				   SYMCLK32_LE0_GATE_DISABLE, enable ? 0 : 1,
221 				   SYMCLK32_ROOT_LE0_GATE_DISABLE, enable ? 0 : 1);
222 		break;
223 	case 1:
224 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
225 				   SYMCLK32_LE1_GATE_DISABLE, enable ? 0 : 1,
226 				   SYMCLK32_ROOT_LE1_GATE_DISABLE, enable ? 0 : 1);
227 		break;
228 	default:
229 		BREAK_TO_DEBUGGER();
230 		return;
231 	}
232 }
233 
234 static void dccg35_set_physymclk_rcg(
235 	struct dccg *dccg,
236 	int inst,
237 	bool enable)
238 {
239 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
240 
241 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk && enable)
242 		return;
243 
244 	switch (inst) {
245 	case 0:
246 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
247 				PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
248 		break;
249 	case 1:
250 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
251 				PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
252 		break;
253 	case 2:
254 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
255 				PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
256 		break;
257 	case 3:
258 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
259 				PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
260 		break;
261 	case 4:
262 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
263 				PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
264 		break;
265 	default:
266 		BREAK_TO_DEBUGGER();
267 		return;
268 	}
269 }
270 
271 static void dccg35_set_symclk_fe_rcg(
272 	struct dccg *dccg,
273 	int inst,
274 	bool enable)
275 {
276 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
277 
278 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)
279 		return;
280 
281 	switch (inst) {
282 	case 0:
283 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
284 				   SYMCLKA_FE_GATE_DISABLE, enable ? 0 : 1);
285 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
286 				   SYMCLKA_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
287 		break;
288 	case 1:
289 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
290 				   SYMCLKB_FE_GATE_DISABLE, enable ? 0 : 1);
291 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
292 				   SYMCLKB_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
293 		break;
294 	case 2:
295 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
296 				   SYMCLKC_FE_GATE_DISABLE, enable ? 0 : 1);
297 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
298 				   SYMCLKC_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
299 		break;
300 	case 3:
301 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
302 				   SYMCLKD_FE_GATE_DISABLE, enable ? 0 : 1);
303 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
304 				   SYMCLKD_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
305 		break;
306 	case 4:
307 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
308 				   SYMCLKE_FE_GATE_DISABLE, enable ? 0 : 1);
309 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
310 				   SYMCLKE_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
311 		break;
312 	default:
313 		BREAK_TO_DEBUGGER();
314 		return;
315 	}
316 }
317 
318 static void dccg35_set_symclk_be_rcg(
319 	struct dccg *dccg,
320 	int inst,
321 	bool enable)
322 {
323 
324 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
325 
326 	/* TBD add symclk_be in rcg control bits */
327 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)
328 		return;
329 
330 	switch (inst) {
331 	case 0:
332 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
333 				   SYMCLKA_GATE_DISABLE, enable ? 0 : 1);
334 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
335 				   SYMCLKA_ROOT_GATE_DISABLE, enable ? 0 : 1);
336 		break;
337 	case 1:
338 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
339 				   SYMCLKB_GATE_DISABLE, enable ? 0 : 1);
340 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
341 				   SYMCLKB_ROOT_GATE_DISABLE, enable ? 0 : 1);
342 		break;
343 	case 2:
344 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
345 				   SYMCLKC_GATE_DISABLE, enable ? 0 : 1);
346 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
347 				   SYMCLKC_ROOT_GATE_DISABLE, enable ? 0 : 1);
348 		break;
349 	case 3:
350 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
351 				   SYMCLKD_GATE_DISABLE, enable ? 0 : 1);
352 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
353 				   SYMCLKD_ROOT_GATE_DISABLE, enable ? 0 : 1);
354 		break;
355 	case 4:
356 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
357 				   SYMCLKE_GATE_DISABLE, enable ? 0 : 1);
358 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
359 				   SYMCLKE_ROOT_GATE_DISABLE, enable ? 0 : 1);
360 		break;
361 	default:
362 		BREAK_TO_DEBUGGER();
363 		return;
364 	}
365 }
366 
367 static void dccg35_set_dtbclk_p_rcg(struct dccg *dccg, int inst, bool enable)
368 {
369 
370 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
371 
372 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)
373 		return;
374 
375 	switch (inst) {
376 	case 0:
377 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, enable ? 0 : 1);
378 		break;
379 	case 1:
380 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, enable ? 0 : 1);
381 		break;
382 	case 2:
383 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P2_GATE_DISABLE, enable ? 0 : 1);
384 		break;
385 	case 3:
386 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P3_GATE_DISABLE, enable ? 0 : 1);
387 		break;
388 	default:
389 		BREAK_TO_DEBUGGER();
390 		break;
391 	}
392 }
393 
394 static void dccg35_set_dppclk_rcg(struct dccg *dccg, int inst, bool allow_rcg)
395 {
396 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
397 
398 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && allow_rcg)
399 		return;
400 
401 	switch (inst) {
402 	case 0:
403 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1);
404 		break;
405 	case 1:
406 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1);
407 		break;
408 	case 2:
409 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1);
410 		break;
411 	case 3:
412 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1);
413 		break;
414 	default:
415 	BREAK_TO_DEBUGGER();
416 		break;
417 	}
418 
419 	/* Wait for clock to ramp */
420 	if (!allow_rcg)
421 		udelay(10);
422 }
423 
424 static void dccg35_set_dpstreamclk_rcg(
425 	struct dccg *dccg,
426 	int inst,
427 	bool enable)
428 {
429 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
430 
431 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream && enable)
432 		return;
433 
434 	switch (inst) {
435 	case 0:
436 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
437 					 DPSTREAMCLK0_GATE_DISABLE, enable ? 0 : 1,
438 					 DPSTREAMCLK0_ROOT_GATE_DISABLE, enable ? 0 : 1);
439 		break;
440 	case 1:
441 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
442 					 DPSTREAMCLK1_GATE_DISABLE, enable ? 0 : 1,
443 					 DPSTREAMCLK1_ROOT_GATE_DISABLE, enable ? 0 : 1);
444 		break;
445 	case 2:
446 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
447 				   DPSTREAMCLK2_GATE_DISABLE, enable ? 0 : 1,
448 				   DPSTREAMCLK2_ROOT_GATE_DISABLE, enable ? 0 : 1);
449 		break;
450 	case 3:
451 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
452 				   DPSTREAMCLK3_GATE_DISABLE, enable ? 0 : 1,
453 				   DPSTREAMCLK3_ROOT_GATE_DISABLE, enable ? 0 : 1);
454 		break;
455 	default:
456 		BREAK_TO_DEBUGGER();
457 		return;
458 	}
459 }
460 
461 static void dccg35_set_smclk32_se_rcg(
462 		struct dccg *dccg,
463 		int inst,
464 		bool enable)
465 {
466 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
467 
468 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)
469 		return;
470 
471 	switch (inst) {
472 	case 0:
473 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
474 					 SYMCLK32_SE0_GATE_DISABLE, enable ? 0 : 1,
475 					 SYMCLK32_ROOT_SE0_GATE_DISABLE, enable ? 0 : 1);
476 		break;
477 	case 1:
478 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
479 					 SYMCLK32_SE1_GATE_DISABLE, enable ? 0 : 1,
480 					 SYMCLK32_ROOT_SE1_GATE_DISABLE, enable ? 0 : 1);
481 		break;
482 	case 2:
483 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
484 					 SYMCLK32_SE2_GATE_DISABLE, enable ? 0 : 1,
485 					 SYMCLK32_ROOT_SE2_GATE_DISABLE, enable ? 0 : 1);
486 		break;
487 	case 3:
488 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
489 					 SYMCLK32_SE3_GATE_DISABLE, enable ? 0 : 1,
490 					 SYMCLK32_ROOT_SE3_GATE_DISABLE, enable ? 0 : 1);
491 		break;
492 	default:
493 		BREAK_TO_DEBUGGER();
494 		return;
495 	}
496 }
497 
498 static void dccg35_set_dsc_clk_src_new(struct dccg *dccg, int inst, enum dsc_clk_source src)
499 {
500 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
501 
502 	/* DSCCLK#_EN=0 switches to refclock from functional clock */
503 
504 	switch (inst) {
505 	case 0:
506 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, src);
507 		break;
508 	case 1:
509 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, src);
510 		break;
511 	case 2:
512 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, src);
513 		break;
514 	case 3:
515 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, src);
516 		break;
517 	default:
518 		BREAK_TO_DEBUGGER();
519 		return;
520 	}
521 }
522 
523 static void dccg35_set_symclk32_se_src_new(
524 	struct dccg *dccg,
525 	int inst,
526 	enum symclk32_se_clk_source src
527 	)
528 {
529 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
530 
531 	switch (inst) {
532 	case 0:
533 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
534 					 SYMCLK32_SE0_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,
535 					 SYMCLK32_SE0_EN,  (src == SYMCLK32_SE_REFCLK) ? 0 : 1);
536 		break;
537 	case 1:
538 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
539 					 SYMCLK32_SE1_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,
540 					 SYMCLK32_SE1_EN, (src == SYMCLK32_SE_REFCLK) ? 0 : 1);
541 		break;
542 	case 2:
543 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
544 					 SYMCLK32_SE2_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,
545 					 SYMCLK32_SE2_EN, (src == SYMCLK32_SE_REFCLK) ? 0 : 1);
546 		break;
547 	case 3:
548 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
549 					 SYMCLK32_SE3_SRC_SEL, (src == SYMCLK32_SE_REFCLK) ? 0 : src,
550 					 SYMCLK32_SE3_EN, (src == SYMCLK32_SE_REFCLK) ? 0 : 1);
551 		break;
552 	default:
553 		BREAK_TO_DEBUGGER();
554 		return;
555 	}
556 }
557 
558 static int
559 dccg35_is_symclk32_se_src_functional_le_new(struct dccg *dccg, int symclk_32_se_inst, int symclk_32_le_inst)
560 {
561 	(void)symclk_32_se_inst;
562 	uint32_t en;
563 	uint32_t src_sel;
564 
565 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
566 
567 	REG_GET_2(SYMCLK32_SE_CNTL, SYMCLK32_SE3_SRC_SEL, &src_sel, SYMCLK32_SE3_EN, &en);
568 
569 	if (en == 1 && src_sel == symclk_32_le_inst)
570 		return 1;
571 
572 	return 0;
573 }
574 
575 
576 static void dccg35_set_symclk32_le_src_new(
577 	struct dccg *dccg,
578 	int inst,
579 	enum symclk32_le_clk_source src)
580 {
581 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
582 
583 	switch (inst) {
584 	case 0:
585 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
586 					 SYMCLK32_LE0_SRC_SEL, (src == SYMCLK32_LE_REFCLK) ? 0 : src,
587 					 SYMCLK32_LE0_EN, (src == SYMCLK32_LE_REFCLK) ? 0 : 1);
588 		break;
589 	case 1:
590 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
591 					 SYMCLK32_LE1_SRC_SEL, (src == SYMCLK32_LE_REFCLK) ? 0 : src,
592 					 SYMCLK32_LE1_EN, (src == SYMCLK32_LE_REFCLK) ? 0 : 1);
593 		break;
594 	default:
595 		BREAK_TO_DEBUGGER();
596 		return;
597 	}
598 }
599 
600 static void dcn35_set_dppclk_src_new(struct dccg *dccg,
601 				 int inst, enum dppclk_clock_source src)
602 {
603 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
604 
605 	switch (inst) {
606 	case 0:
607 		REG_UPDATE(DPPCLK_CTRL, DPPCLK0_EN, src);
608 		break;
609 	case 1:
610 		REG_UPDATE(DPPCLK_CTRL, DPPCLK1_EN, src);
611 		break;
612 	case 2:
613 		REG_UPDATE(DPPCLK_CTRL, DPPCLK2_EN, src);
614 		break;
615 	case 3:
616 		REG_UPDATE(DPPCLK_CTRL, DPPCLK3_EN, src);
617 		break;
618 	default:
619 	BREAK_TO_DEBUGGER();
620 		break;
621 	}
622 }
623 
624 static void dccg35_set_dtbclk_p_src_new(
625 	struct dccg *dccg,
626 	enum dtbclk_source src,
627 	int inst)
628 {
629 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
630 
631 	/* If DTBCLK_P#_EN is 0 refclock is selected as functional clock
632 	 * If DTBCLK_P#_EN is 1 functional clock is selected as DTBCLK_P#_SRC_SEL
633 	 */
634 
635 	switch (inst) {
636 	case 0:
637 		REG_UPDATE_2(DTBCLK_P_CNTL,
638 					 DTBCLK_P0_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,
639 					 DTBCLK_P0_EN, (src == DTBCLK_REFCLK) ? 0 : 1);
640 		break;
641 	case 1:
642 		REG_UPDATE_2(DTBCLK_P_CNTL,
643 					 DTBCLK_P1_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,
644 					 DTBCLK_P1_EN, (src == DTBCLK_REFCLK) ? 0 : 1);
645 		break;
646 	case 2:
647 		REG_UPDATE_2(DTBCLK_P_CNTL,
648 					 DTBCLK_P2_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,
649 					 DTBCLK_P2_EN, (src == DTBCLK_REFCLK) ? 0 : 1);
650 		break;
651 	case 3:
652 		REG_UPDATE_2(DTBCLK_P_CNTL,
653 					 DTBCLK_P3_SRC_SEL, (src == DTBCLK_REFCLK) ? 0 : src,
654 					 DTBCLK_P3_EN, (src == DTBCLK_REFCLK) ? 0 : 1);
655 		break;
656 	default:
657 		BREAK_TO_DEBUGGER();
658 		return;
659 	}
660 }
661 
662 static void dccg35_set_dpstreamclk_src_new(
663 	struct dccg *dccg,
664 	enum dp_stream_clk_source src,
665 	int inst)
666 {
667 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
668 
669 	switch (inst) {
670 	case 0:
671 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK0_EN,
672 					 (src == DP_STREAM_REFCLK) ? 0 : 1,
673 					 DPSTREAMCLK0_SRC_SEL,
674 					 (src == DP_STREAM_REFCLK) ? 0 : src);
675 		break;
676 	case 1:
677 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN,
678 					 (src == DP_STREAM_REFCLK) ? 0 : 1,
679 					 DPSTREAMCLK1_SRC_SEL,
680 					 (src == DP_STREAM_REFCLK) ? 0 : src);
681 
682 		break;
683 	case 2:
684 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN,
685 					 (src == DP_STREAM_REFCLK) ? 0 : 1,
686 					 DPSTREAMCLK2_SRC_SEL,
687 					 (src == DP_STREAM_REFCLK) ? 0 : src);
688 
689 		break;
690 	case 3:
691 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN,
692 					 (src == DP_STREAM_REFCLK) ? 0 : 1,
693 					 DPSTREAMCLK3_SRC_SEL,
694 					 (src == DP_STREAM_REFCLK) ? 0 : src);
695 		break;
696 	default:
697 		BREAK_TO_DEBUGGER();
698 		return;
699 	}
700 }
701 
702 static void dccg35_set_physymclk_src_new(
703 	struct dccg *dccg,
704 	enum physymclk_source src,
705 	int inst)
706 {
707 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
708 
709 	switch (inst) {
710 	case 0:
711 		REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, PHYASYMCLK_EN,
712 					 (src == PHYSYMCLK_REFCLK) ? 0 : 1,
713 					 PHYASYMCLK_SRC_SEL,
714 					 (src == PHYSYMCLK_REFCLK) ? 0 : src);
715 		break;
716 	case 1:
717 		REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, PHYBSYMCLK_EN,
718 					 (src == PHYSYMCLK_REFCLK) ? 0 : 1,
719 					 PHYBSYMCLK_SRC_SEL,
720 					 (src == PHYSYMCLK_REFCLK) ? 0 : src);
721 		break;
722 	case 2:
723 		REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, PHYCSYMCLK_EN,
724 					 (src == PHYSYMCLK_REFCLK) ? 0 : 1,
725 					 PHYCSYMCLK_SRC_SEL,
726 					 (src == PHYSYMCLK_REFCLK) ? 0 : src);
727 		break;
728 	case 3:
729 		REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, PHYDSYMCLK_EN,
730 					 (src == PHYSYMCLK_REFCLK) ? 0 : 1,
731 					 PHYDSYMCLK_SRC_SEL,
732 					 (src == PHYSYMCLK_REFCLK) ? 0 : src);
733 		break;
734 	case 4:
735 		REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, PHYESYMCLK_EN,
736 					 (src == PHYSYMCLK_REFCLK) ? 0 : 1,
737 					 PHYESYMCLK_SRC_SEL,
738 					 (src == PHYSYMCLK_REFCLK) ? 0 : src);
739 		break;
740 	default:
741 		BREAK_TO_DEBUGGER();
742 		return;
743 	}
744 }
745 
746 static void dccg35_set_symclk_be_src_new(
747 	struct dccg *dccg,
748 	enum symclk_be_source src,
749 	int inst)
750 {
751 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
752 
753 	switch (inst) {
754 	case 0:
755 		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,
756 					 SYMCLKA_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,
757 					 SYMCLKA_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);
758 		break;
759 	case 1:
760 		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,
761 					 SYMCLKB_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,
762 					 SYMCLKB_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);
763 		break;
764 	case 2:
765 		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,
766 					 SYMCLKC_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,
767 					 SYMCLKC_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);
768 		break;
769 	case 3:
770 		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,
771 					 SYMCLKD_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,
772 					 SYMCLKD_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);
773 		break;
774 	case 4:
775 		REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,
776 					 SYMCLKE_CLOCK_ENABLE, (src == SYMCLK_BE_REFCLK) ? 0 : 1,
777 					 SYMCLKE_SRC_SEL, (src == SYMCLK_BE_REFCLK) ? 0 : src);
778 		break;
779 	}
780 }
781 
782 static int dccg35_is_symclk_fe_src_functional_be(struct dccg *dccg,
783 												 int symclk_fe_inst,
784 												 int symclk_be_inst)
785 {
786 
787 	uint32_t en = 0;
788 	uint32_t src_sel = 0;
789 
790 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
791 
792 	switch (symclk_fe_inst) {
793 	case 0:
794 		REG_GET_2(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_SRC_SEL, &src_sel, SYMCLKA_FE_EN, &en);
795 		break;
796 	case 1:
797 		REG_GET_2(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_SRC_SEL, &src_sel, SYMCLKB_FE_EN, &en);
798 		break;
799 	case 2:
800 		REG_GET_2(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_SRC_SEL, &src_sel, SYMCLKC_FE_EN, &en);
801 		break;
802 	case 3:
803 		REG_GET_2(SYMCLKD_CLOCK_ENABLE, SYMCLKD_FE_SRC_SEL, &src_sel, SYMCLKD_FE_EN, &en);
804 		break;
805 	case 4:
806 		REG_GET_2(SYMCLKE_CLOCK_ENABLE, SYMCLKE_FE_SRC_SEL, &src_sel, SYMCLKE_FE_EN, &en);
807 		break;
808 	}
809 
810 	if (en == 1 && src_sel == symclk_be_inst)
811 		return 1;
812 
813 	return 0;
814 }
815 
816 static void dccg35_set_symclk_fe_src_new(struct dccg *dccg, enum symclk_fe_source src, int inst)
817 {
818 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
819 
820 	switch (inst) {
821 	case 0:
822 		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,
823 					 SYMCLKA_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,
824 					 SYMCLKA_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);
825 		break;
826 	case 1:
827 		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,
828 					 SYMCLKB_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,
829 					 SYMCLKB_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);
830 		break;
831 	case 2:
832 		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,
833 					 SYMCLKC_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,
834 					 SYMCLKC_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);
835 		break;
836 	case 3:
837 		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,
838 					 SYMCLKD_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,
839 					 SYMCLKD_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);
840 		break;
841 	case 4:
842 		REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,
843 					 SYMCLKE_FE_EN, (src == SYMCLK_FE_REFCLK) ? 0 : 1,
844 					 SYMCLKE_FE_SRC_SEL, (src == SYMCLK_FE_REFCLK) ? 0 : src);
845 		break;
846 	}
847 }
848 
849 static uint32_t dccg35_is_fe_rcg(struct dccg *dccg, int inst)
850 {
851 	uint32_t enable = 0;
852 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
853 
854 	switch (inst) {
855 	case 0:
856 		REG_GET(DCCG_GATE_DISABLE_CNTL5,
857 				SYMCLKA_FE_ROOT_GATE_DISABLE, &enable);
858 		break;
859 	case 1:
860 		REG_GET(DCCG_GATE_DISABLE_CNTL5,
861 				SYMCLKB_FE_ROOT_GATE_DISABLE, &enable);
862 		break;
863 	case 2:
864 		REG_GET(DCCG_GATE_DISABLE_CNTL5,
865 				SYMCLKC_FE_ROOT_GATE_DISABLE, &enable);
866 		break;
867 	case 3:
868 		REG_GET(DCCG_GATE_DISABLE_CNTL5,
869 				SYMCLKD_FE_ROOT_GATE_DISABLE, &enable);
870 		break;
871 	case 4:
872 		REG_GET(DCCG_GATE_DISABLE_CNTL5,
873 				SYMCLKE_FE_ROOT_GATE_DISABLE, &enable);
874 		break;
875 	default:
876 		BREAK_TO_DEBUGGER();
877 		break;
878 	}
879 	return enable;
880 }
881 
882 static uint32_t dccg35_is_symclk32_se_rcg(struct dccg *dccg, int inst)
883 {
884 	uint32_t disable_l1 = 0;
885 	uint32_t disable_l2 = 0;
886 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
887 
888 	switch (inst) {
889 	case 0:
890 		REG_GET_2(DCCG_GATE_DISABLE_CNTL3,
891 				  SYMCLK32_SE0_GATE_DISABLE, &disable_l1,
892 				  SYMCLK32_ROOT_SE0_GATE_DISABLE, &disable_l2);
893 		break;
894 	case 1:
895 		REG_GET_2(DCCG_GATE_DISABLE_CNTL3,
896 				  SYMCLK32_SE1_GATE_DISABLE, &disable_l1,
897 				  SYMCLK32_ROOT_SE1_GATE_DISABLE, &disable_l2);
898 		break;
899 	case 2:
900 		REG_GET_2(DCCG_GATE_DISABLE_CNTL3,
901 				  SYMCLK32_SE2_GATE_DISABLE, &disable_l1,
902 				  SYMCLK32_ROOT_SE2_GATE_DISABLE, &disable_l2);
903 		break;
904 	case 3:
905 		REG_GET_2(DCCG_GATE_DISABLE_CNTL3,
906 				  SYMCLK32_SE3_GATE_DISABLE, &disable_l1,
907 				  SYMCLK32_ROOT_SE3_GATE_DISABLE, &disable_l2);
908 		break;
909 	default:
910 		BREAK_TO_DEBUGGER();
911 		return 0;
912 	}
913 
914 	/* return true if either block level or DCCG level gating is active */
915 	return (disable_l1 | disable_l2);
916 }
917 
918 static void dccg35_enable_symclk_fe_new(
919 	struct dccg *dccg,
920 	int inst,
921 	enum symclk_fe_source src)
922 {
923 	dccg35_set_symclk_fe_rcg(dccg, inst, false);
924 	dccg35_set_symclk_fe_src_new(dccg, src, inst);
925 }
926 
927 static void dccg35_disable_symclk_fe_new(
928 	struct dccg *dccg,
929 	int inst)
930 {
931 	dccg35_set_symclk_fe_src_new(dccg, SYMCLK_FE_REFCLK, inst);
932 	dccg35_set_symclk_fe_rcg(dccg, inst, true);
933 }
934 
935 static void dccg35_enable_symclk_be_new(
936 	struct dccg *dccg,
937 	int inst,
938 	enum symclk_be_source src)
939 {
940 	dccg35_set_symclk_be_rcg(dccg, inst, false);
941 	dccg35_set_symclk_be_src_new(dccg, inst, src);
942 }
943 
944 static void dccg35_disable_symclk_be_new(
945 	struct dccg *dccg,
946 	int inst)
947 {
948 	int i;
949 
950 	/* Switch from functional clock to refclock */
951 	dccg35_set_symclk_be_src_new(dccg, inst, SYMCLK_BE_REFCLK);
952 
953 	/* Check if any other SE connected LE and disable them */
954 	for (i = 0; i < 4; i++) {
955 		/* Make sure FE is not already in RCG */
956 		if (dccg35_is_fe_rcg(dccg, i) == 0) {
957 			if (dccg35_is_symclk_fe_src_functional_be(dccg, i, inst))
958 				dccg35_disable_symclk_fe_new(dccg, i);
959 		}
960 	}
961 	/* Safe to RCG SYMCLK*/
962 	dccg35_set_symclk_be_rcg(dccg, inst, true);
963 }
964 
965 static void dccg35_enable_symclk32_se_new(
966 	struct dccg *dccg,
967 	int inst,
968 	enum symclk32_se_clk_source src)
969 {
970 	dccg35_set_symclk32_se_rcg(dccg, inst, false);
971 	dccg35_set_symclk32_se_src_new(dccg, inst, src);
972 }
973 
974 static void dccg35_disable_symclk32_se_new(
975 	struct dccg *dccg,
976 	int inst)
977 {
978 	dccg35_set_symclk32_se_src_new(dccg, SYMCLK32_SE_REFCLK, inst);
979 	dccg35_set_symclk32_se_rcg(dccg, inst, true);
980 }
981 
982 static void dccg35_enable_symclk32_le_new(
983 	struct dccg *dccg,
984 	int inst,
985 	enum symclk32_le_clk_source src)
986 {
987 	dccg35_set_symclk32_le_rcg(dccg, inst, false);
988 	dccg35_set_symclk32_le_src_new(dccg, inst, src);
989 }
990 
991 static void dccg35_disable_symclk32_le_new(
992 	struct dccg *dccg,
993 	int inst)
994 {
995 	int i;
996 
997 	/* Switch from functional clock to refclock */
998 	dccg35_set_symclk32_le_src_new(dccg, inst, SYMCLK32_LE_REFCLK);
999 
1000 	/* Check if any SE are connected and disable SE as well */
1001 	for (i = 0; i < 4; i++) {
1002 		/* Make sure FE is not already in RCG */
1003 		if (dccg35_is_symclk32_se_rcg(dccg, i) == 0) {
1004 			/* Disable and SE connected to this LE before RCG */
1005 			if (dccg35_is_symclk32_se_src_functional_le_new(dccg, i, inst))
1006 				dccg35_disable_symclk32_se_new(dccg, i);
1007 		}
1008 	}
1009 	/* Safe to RCG SYM32_LE*/
1010 	dccg35_set_symclk32_le_rcg(dccg, inst, true);
1011 }
1012 
1013 static void dccg35_enable_physymclk_new(struct dccg *dccg,
1014 					int inst,
1015 					enum physymclk_source src)
1016 {
1017 	dccg35_set_physymclk_rcg(dccg, inst, false);
1018 	dccg35_set_physymclk_src_new(dccg, src, inst);
1019 }
1020 
1021 static void dccg35_disable_physymclk_new(struct dccg *dccg,
1022 										 int inst)
1023 {
1024 	dccg35_set_physymclk_src_new(dccg, PHYSYMCLK_REFCLK, inst);
1025 	dccg35_set_physymclk_rcg(dccg, inst, true);
1026 }
1027 
1028 static void dccg35_enable_dpp_clk_new(
1029 	struct dccg *dccg,
1030 	int inst,
1031 	enum dppclk_clock_source src)
1032 {
1033 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1034 	/* Sanitize inst before use in array de-ref */
1035 	if (inst < 0) {
1036 		BREAK_TO_DEBUGGER();
1037 		return;
1038 	}
1039 	dccg35_set_dppclk_rcg(dccg, inst, false);
1040 	dcn35_set_dppclk_src_new(dccg, inst, src);
1041 	/* Switch DPP clock to DTO */
1042 	REG_SET_2(DPPCLK_DTO_PARAM[inst], 0,
1043 			  DPPCLK0_DTO_PHASE, 0xFF,
1044 			  DPPCLK0_DTO_MODULO, 0xFF);
1045 }
1046 
1047 
1048 static void dccg35_disable_dpp_clk_new(
1049 	struct dccg *dccg,
1050 	int inst)
1051 {
1052 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1053 	/* Sanitize inst before use in array de-ref */
1054 	if (inst < 0) {
1055 		BREAK_TO_DEBUGGER();
1056 		return;
1057 	}
1058 	dcn35_set_dppclk_src_new(dccg, inst, DPP_REFCLK);
1059 	REG_SET_2(DPPCLK_DTO_PARAM[inst], 0,
1060 			  DPPCLK0_DTO_PHASE, 0,
1061 			  DPPCLK0_DTO_MODULO, 1);
1062 	dccg35_set_dppclk_rcg(dccg, inst, true);
1063 }
1064 
1065 static void dccg35_disable_dscclk_new(struct dccg *dccg,
1066 									  int inst)
1067 {
1068 	dccg35_set_dsc_clk_src_new(dccg, inst, DSC_CLK_REF_CLK);
1069 	dccg35_set_dsc_clk_rcg(dccg, inst, true);
1070 }
1071 
1072 static void dccg35_enable_dscclk_new(struct dccg *dccg,
1073 									 int inst,
1074 									 enum dsc_clk_source src)
1075 {
1076 	dccg35_set_dsc_clk_rcg(dccg, inst, false);
1077 	dccg35_set_dsc_clk_src_new(dccg, inst, src);
1078 }
1079 
1080 static void dccg35_enable_dtbclk_p_new(struct dccg *dccg,
1081 									   enum dtbclk_source src,
1082 									   int inst)
1083 {
1084 	dccg35_set_dtbclk_p_rcg(dccg, inst, false);
1085 	dccg35_set_dtbclk_p_src_new(dccg, src, inst);
1086 }
1087 
1088 static void dccg35_disable_dtbclk_p_new(struct dccg *dccg,
1089 										int inst)
1090 {
1091 	dccg35_set_dtbclk_p_src_new(dccg, DTBCLK_REFCLK, inst);
1092 	dccg35_set_dtbclk_p_rcg(dccg, inst, true);
1093 }
1094 
1095 static void dccg35_disable_dpstreamclk_new(struct dccg *dccg,
1096 										  int inst)
1097 {
1098 	dccg35_set_dpstreamclk_src_new(dccg, DP_STREAM_REFCLK, inst);
1099 	dccg35_set_dpstreamclk_rcg(dccg, inst, true);
1100 }
1101 
1102 static void dccg35_enable_dpstreamclk_new(struct dccg *dccg,
1103 										   enum dp_stream_clk_source src,
1104 										   int inst)
1105 {
1106 	dccg35_set_dpstreamclk_rcg(dccg, inst, false);
1107 	dccg35_set_dpstreamclk_src_new(dccg, src, inst);
1108 }
1109 
1110 void dccg35_trigger_dio_fifo_resync(struct dccg *dccg)
1111 {
1112 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1113 	uint32_t dispclk_rdivider_value = 0;
1114 
1115 	REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, &dispclk_rdivider_value);
1116 	if (dispclk_rdivider_value != 0)
1117 		REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value);
1118 }
1119 
1120 static void dccg35_wait_for_dentist_change_done(
1121 	struct dccg *dccg)
1122 {
1123 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1124 
1125 	uint32_t dentist_dispclk_value = REG_READ(DENTIST_DISPCLK_CNTL);
1126 
1127 	REG_WRITE(DENTIST_DISPCLK_CNTL, dentist_dispclk_value);
1128 	REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000);
1129 }
1130 
1131 static void dcn35_set_dppclk_enable(struct dccg *dccg,
1132 				 uint32_t dpp_inst, uint32_t enable)
1133 {
1134 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1135 
1136 
1137 	switch (dpp_inst) {
1138 	case 0:
1139 		REG_UPDATE(DPPCLK_CTRL, DPPCLK0_EN, enable);
1140 		break;
1141 	case 1:
1142 		REG_UPDATE(DPPCLK_CTRL, DPPCLK1_EN, enable);
1143 		break;
1144 	case 2:
1145 		REG_UPDATE(DPPCLK_CTRL, DPPCLK2_EN, enable);
1146 		break;
1147 	case 3:
1148 		REG_UPDATE(DPPCLK_CTRL, DPPCLK3_EN, enable);
1149 		break;
1150 	default:
1151 		break;
1152 	}
1153 	DC_LOG_DEBUG("%s: dpp_inst(%d) DPPCLK_EN = %d\n", __func__, dpp_inst, enable);
1154 
1155 }
1156 
1157 void dccg35_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
1158 {
1159 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1160 
1161 	if (dccg->dpp_clock_gated[dpp_inst]) {
1162 		/*
1163 		 * Do not update the DPPCLK DTO if the clock is stopped.
1164 		 */
1165 		return;
1166 	}
1167 
1168 	if (dccg->ref_dppclk && req_dppclk) {
1169 		int ref_dppclk = dccg->ref_dppclk;
1170 		int modulo, phase;
1171 
1172 		// phase / modulo = dpp pipe clk / dpp global clk
1173 		modulo = 0xff;   // use FF at the end
1174 		phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;
1175 
1176 		if (phase > 0xff) {
1177 			ASSERT(false);
1178 			phase = 0xff;
1179 		}
1180 		dccg35_set_dppclk_rcg(dccg, dpp_inst, false);
1181 
1182 		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
1183 				DPPCLK0_DTO_PHASE, phase,
1184 				DPPCLK0_DTO_MODULO, modulo);
1185 
1186 		dcn35_set_dppclk_enable(dccg, dpp_inst, true);
1187 	} else {
1188 		dcn35_set_dppclk_enable(dccg, dpp_inst, false);
1189 		dccg35_set_dppclk_rcg(dccg, dpp_inst, true);
1190 	}
1191 	udelay(10);
1192 	dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
1193 }
1194 
1195 static void dccg35_set_dppclk_root_clock_gating(struct dccg *dccg,
1196 		 uint32_t dpp_inst, uint32_t disallow_rcg)
1197 {
1198 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1199 
1200 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && !disallow_rcg)
1201 		return;
1202 
1203 
1204 	switch (dpp_inst) {
1205 	case 0:
1206 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, disallow_rcg);
1207 		break;
1208 	case 1:
1209 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, disallow_rcg);
1210 		break;
1211 	case 2:
1212 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, disallow_rcg);
1213 		break;
1214 	case 3:
1215 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, disallow_rcg);
1216 		break;
1217 	default:
1218 		break;
1219 	}
1220 
1221 	/* Wait for clock to ramp */
1222 	if (disallow_rcg)
1223 		udelay(10);
1224 }
1225 
1226 static void dccg35_get_pixel_rate_div(
1227 		struct dccg *dccg,
1228 		uint32_t otg_inst,
1229 		uint32_t *k1,
1230 		uint32_t *k2)
1231 {
1232 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1233 	uint32_t val_k1 = PIXEL_RATE_DIV_NA, val_k2 = PIXEL_RATE_DIV_NA;
1234 
1235 	*k1 = PIXEL_RATE_DIV_NA;
1236 	*k2 = PIXEL_RATE_DIV_NA;
1237 
1238 	switch (otg_inst) {
1239 	case 0:
1240 		REG_GET_2(OTG_PIXEL_RATE_DIV,
1241 			OTG0_PIXEL_RATE_DIVK1, &val_k1,
1242 			OTG0_PIXEL_RATE_DIVK2, &val_k2);
1243 		break;
1244 	case 1:
1245 		REG_GET_2(OTG_PIXEL_RATE_DIV,
1246 			OTG1_PIXEL_RATE_DIVK1, &val_k1,
1247 			OTG1_PIXEL_RATE_DIVK2, &val_k2);
1248 		break;
1249 	case 2:
1250 		REG_GET_2(OTG_PIXEL_RATE_DIV,
1251 			OTG2_PIXEL_RATE_DIVK1, &val_k1,
1252 			OTG2_PIXEL_RATE_DIVK2, &val_k2);
1253 		break;
1254 	case 3:
1255 		REG_GET_2(OTG_PIXEL_RATE_DIV,
1256 			OTG3_PIXEL_RATE_DIVK1, &val_k1,
1257 			OTG3_PIXEL_RATE_DIVK2, &val_k2);
1258 		break;
1259 	default:
1260 		BREAK_TO_DEBUGGER();
1261 		return;
1262 	}
1263 
1264 	*k1 = val_k1;
1265 	*k2 = val_k2;
1266 }
1267 
1268 static void dccg35_set_pixel_rate_div(
1269 		struct dccg *dccg,
1270 		uint32_t otg_inst,
1271 		enum pixel_rate_div k1,
1272 		enum pixel_rate_div k2)
1273 {
1274 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1275 	uint32_t cur_k1 = PIXEL_RATE_DIV_NA;
1276 	uint32_t cur_k2 = PIXEL_RATE_DIV_NA;
1277 
1278 
1279 	// Don't program 0xF into the register field. Not valid since
1280 	// K1 / K2 field is only 1 / 2 bits wide
1281 	if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
1282 		BREAK_TO_DEBUGGER();
1283 		return;
1284 	}
1285 
1286 	dccg35_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
1287 	if (k1 == cur_k1 && k2 == cur_k2)
1288 		return;
1289 
1290 	switch (otg_inst) {
1291 	case 0:
1292 		REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
1293 				OTG0_PIXEL_RATE_DIVK1, k1,
1294 				OTG0_PIXEL_RATE_DIVK2, k2);
1295 		break;
1296 	case 1:
1297 		REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
1298 				OTG1_PIXEL_RATE_DIVK1, k1,
1299 				OTG1_PIXEL_RATE_DIVK2, k2);
1300 		break;
1301 	case 2:
1302 		REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
1303 				OTG2_PIXEL_RATE_DIVK1, k1,
1304 				OTG2_PIXEL_RATE_DIVK2, k2);
1305 		break;
1306 	case 3:
1307 		REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
1308 				OTG3_PIXEL_RATE_DIVK1, k1,
1309 				OTG3_PIXEL_RATE_DIVK2, k2);
1310 		break;
1311 	default:
1312 		BREAK_TO_DEBUGGER();
1313 		return;
1314 	}
1315 	if (otg_inst < 4)
1316 		dccg35_wait_for_dentist_change_done(dccg);
1317 }
1318 
1319 static void dccg35_set_dtbclk_p_src(
1320 		struct dccg *dccg,
1321 		enum streamclk_source src,
1322 		uint32_t otg_inst)
1323 {
1324 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1325 
1326 	uint32_t p_src_sel = 0; /* selects dprefclk */
1327 	if (src == DTBCLK0)
1328 		p_src_sel = 2;  /* selects dtbclk0 */
1329 
1330 	switch (otg_inst) {
1331 	case 0:
1332 		if (src == REFCLK)
1333 			REG_UPDATE(DTBCLK_P_CNTL,
1334 					DTBCLK_P0_EN, 0);
1335 		else
1336 			REG_UPDATE_2(DTBCLK_P_CNTL,
1337 					DTBCLK_P0_SRC_SEL, p_src_sel,
1338 					DTBCLK_P0_EN, 1);
1339 		break;
1340 	case 1:
1341 		if (src == REFCLK)
1342 			REG_UPDATE(DTBCLK_P_CNTL,
1343 					DTBCLK_P1_EN, 0);
1344 		else
1345 			REG_UPDATE_2(DTBCLK_P_CNTL,
1346 					DTBCLK_P1_SRC_SEL, p_src_sel,
1347 					DTBCLK_P1_EN, 1);
1348 		break;
1349 	case 2:
1350 		if (src == REFCLK)
1351 			REG_UPDATE(DTBCLK_P_CNTL,
1352 					DTBCLK_P2_EN, 0);
1353 		else
1354 			REG_UPDATE_2(DTBCLK_P_CNTL,
1355 					DTBCLK_P2_SRC_SEL, p_src_sel,
1356 					DTBCLK_P2_EN, 1);
1357 		break;
1358 	case 3:
1359 		if (src == REFCLK)
1360 			REG_UPDATE(DTBCLK_P_CNTL,
1361 					DTBCLK_P3_EN, 0);
1362 		else
1363 			REG_UPDATE_2(DTBCLK_P_CNTL,
1364 					DTBCLK_P3_SRC_SEL, p_src_sel,
1365 					DTBCLK_P3_EN, 1);
1366 		break;
1367 	default:
1368 		BREAK_TO_DEBUGGER();
1369 		return;
1370 	}
1371 
1372 }
1373 
1374 /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
1375 static void dccg35_set_dtbclk_dto(
1376 		struct dccg *dccg,
1377 		const struct dtbclk_dto_params *params)
1378 {
1379 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1380 	/* DTO Output Rate / Pixel Rate = 1/4 */
1381 	int req_dtbclk_khz = params->pixclk_khz / 4;
1382 
1383 	if (params->ref_dtbclk_khz && req_dtbclk_khz) {
1384 		uint32_t modulo, phase;
1385 
1386 		switch (params->otg_inst) {
1387 		case 0:
1388 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, 1);
1389 			break;
1390 		case 1:
1391 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, 1);
1392 			break;
1393 		case 2:
1394 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P2_GATE_DISABLE, 1);
1395 			break;
1396 		case 3:
1397 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P3_GATE_DISABLE, 1);
1398 			break;
1399 		}
1400 
1401 		// phase / modulo = dtbclk / dtbclk ref
1402 		modulo = params->ref_dtbclk_khz * 1000;
1403 		phase = req_dtbclk_khz * 1000;
1404 
1405 		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
1406 		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
1407 
1408 		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
1409 				DTBCLK_DTO_ENABLE[params->otg_inst], 1);
1410 
1411 		REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
1412 				DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
1413 				1, 100);
1414 
1415 		/* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */
1416 		dccg35_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
1417 
1418 		/* The recommended programming sequence to enable DTBCLK DTO to generate
1419 		 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
1420 		 * be set only after DTO is enabled.
1421 		 * PIPEx_DTO_SRC_SEL should not be programmed during DTBCLK update since OTG may still be on, and the
1422 		 * programming is handled in program_pix_clk() regardless, so it can be removed from here.
1423 		 */
1424 		DC_LOG_DEBUG("%s: OTG%d DTBCLK DTO enabled: pixclk_khz=%d, ref_dtbclk_khz=%d, req_dtbclk_khz=%d, phase=%d, modulo=%d\n",
1425 				__func__, params->otg_inst, params->pixclk_khz,
1426 				params->ref_dtbclk_khz, req_dtbclk_khz, phase, modulo);
1427 
1428 	} else if (!params->ref_dtbclk_khz && !req_dtbclk_khz) {
1429 		switch (params->otg_inst) {
1430 		case 0:
1431 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, 0);
1432 			break;
1433 		case 1:
1434 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, 0);
1435 			break;
1436 		case 2:
1437 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P2_GATE_DISABLE, 0);
1438 			break;
1439 		case 3:
1440 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P3_GATE_DISABLE, 0);
1441 			break;
1442 		}
1443 
1444 		/**
1445 		 * PIPEx_DTO_SRC_SEL should not be programmed during DTBCLK update since OTG may still be on, and the
1446 		 * programming is handled in program_pix_clk() regardless, so it can be removed from here.
1447 		 */
1448 		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
1449 				DTBCLK_DTO_ENABLE[params->otg_inst], 0);
1450 
1451 		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
1452 		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
1453 
1454 		DC_LOG_DEBUG("%s: OTG%d DTBCLK DTO disabled\n", __func__, params->otg_inst);
1455 	}
1456 }
1457 
1458 static void dccg35_set_dpstreamclk(
1459 		struct dccg *dccg,
1460 		enum streamclk_source src,
1461 		int otg_inst,
1462 		int dp_hpo_inst)
1463 {
1464 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1465 
1466 	/* set the dtbclk_p source */
1467 	dccg35_set_dtbclk_p_src(dccg, src, otg_inst);
1468 
1469 	/* enabled to select one of the DTBCLKs for pipe */
1470 	switch (dp_hpo_inst) {
1471 	case 0:
1472 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK0_EN,
1473 				(src == REFCLK) ? 0 : 1, DPSTREAMCLK0_SRC_SEL, otg_inst);
1474 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1475 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);
1476 		break;
1477 	case 1:
1478 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN,
1479 				(src == REFCLK) ? 0 : 1, DPSTREAMCLK1_SRC_SEL, otg_inst);
1480 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1481 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);
1482 		break;
1483 	case 2:
1484 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN,
1485 				(src == REFCLK) ? 0 : 1, DPSTREAMCLK2_SRC_SEL, otg_inst);
1486 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1487 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);
1488 		break;
1489 	case 3:
1490 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN,
1491 				(src == REFCLK) ? 0 : 1, DPSTREAMCLK3_SRC_SEL, otg_inst);
1492 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1493 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);
1494 		break;
1495 	default:
1496 		BREAK_TO_DEBUGGER();
1497 		return;
1498 	}
1499 	DC_LOG_DEBUG("%s: dp_hpo_inst(%d) DPSTREAMCLK_EN = %d, DPSTREAMCLK_SRC_SEL = %d\n",
1500 			__func__, dp_hpo_inst, (src == REFCLK) ? 0 : 1, otg_inst);
1501 }
1502 
1503 void dccg35_set_dpstreamclk_root_clock_gating(struct dccg *dccg, int dp_hpo_inst, bool enable)
1504 {
1505 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1506 
1507 	switch (dp_hpo_inst) {
1508 	case 0:
1509 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
1510 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_ROOT_GATE_DISABLE, enable ? 1 : 0);
1511 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_GATE_DISABLE, enable ? 1 : 0);
1512 		}
1513 		break;
1514 	case 1:
1515 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
1516 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_ROOT_GATE_DISABLE, enable ? 1 : 0);
1517 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_GATE_DISABLE, enable ? 1 : 0);
1518 		}
1519 		break;
1520 	case 2:
1521 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
1522 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_ROOT_GATE_DISABLE, enable ? 1 : 0);
1523 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_GATE_DISABLE, enable ? 1 : 0);
1524 		}
1525 		break;
1526 	case 3:
1527 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
1528 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_ROOT_GATE_DISABLE, enable ? 1 : 0);
1529 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_GATE_DISABLE, enable ? 1 : 0);
1530 		}
1531 		break;
1532 	default:
1533 		BREAK_TO_DEBUGGER();
1534 		return;
1535 	}
1536 	DC_LOG_DEBUG("%s: dp_hpo_inst(%d) DPSTREAMCLK_ROOT_GATE_DISABLE = %d\n",
1537 			__func__, dp_hpo_inst, enable ? 1 : 0);
1538 }
1539 
1540 
1541 
1542 static void dccg35_set_physymclk_root_clock_gating(
1543 		struct dccg *dccg,
1544 		int phy_inst,
1545 		bool enable)
1546 {
1547 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1548 
1549 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
1550 		return;
1551 
1552 	switch (phy_inst) {
1553 	case 0:
1554 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
1555 				PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
1556 		break;
1557 	case 1:
1558 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
1559 				PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
1560 		break;
1561 	case 2:
1562 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
1563 				PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
1564 		break;
1565 	case 3:
1566 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
1567 				PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
1568 		break;
1569 	case 4:
1570 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
1571 				PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
1572 		break;
1573 	default:
1574 		BREAK_TO_DEBUGGER();
1575 		return;
1576 	}
1577 	DC_LOG_DEBUG("%s: dpp_inst(%d) PHYESYMCLK_ROOT_GATE_DISABLE: %d\n", __func__, phy_inst, enable ? 0 : 1);
1578 
1579 }
1580 
1581 static void dccg35_set_physymclk(
1582 		struct dccg *dccg,
1583 		int phy_inst,
1584 		enum physymclk_clock_source clk_src,
1585 		bool force_enable)
1586 {
1587 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1588 
1589 	/* Force PHYSYMCLK on and Select phyd32clk as the source of clock which is output to PHY through DCIO */
1590 	switch (phy_inst) {
1591 	case 0:
1592 		if (force_enable) {
1593 			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
1594 					PHYASYMCLK_EN, 1,
1595 					PHYASYMCLK_SRC_SEL, clk_src);
1596 		} else {
1597 			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
1598 					PHYASYMCLK_EN, 0,
1599 					PHYASYMCLK_SRC_SEL, 0);
1600 		}
1601 		break;
1602 	case 1:
1603 		if (force_enable) {
1604 			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
1605 					PHYBSYMCLK_EN, 1,
1606 					PHYBSYMCLK_SRC_SEL, clk_src);
1607 		} else {
1608 			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
1609 					PHYBSYMCLK_EN, 0,
1610 					PHYBSYMCLK_SRC_SEL, 0);
1611 		}
1612 		break;
1613 	case 2:
1614 		if (force_enable) {
1615 			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
1616 					PHYCSYMCLK_EN, 1,
1617 					PHYCSYMCLK_SRC_SEL, clk_src);
1618 		} else {
1619 			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
1620 					PHYCSYMCLK_EN, 0,
1621 					PHYCSYMCLK_SRC_SEL, 0);
1622 		}
1623 		break;
1624 	case 3:
1625 		if (force_enable) {
1626 			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
1627 					PHYDSYMCLK_EN, 1,
1628 					PHYDSYMCLK_SRC_SEL, clk_src);
1629 		} else {
1630 			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
1631 					PHYDSYMCLK_EN, 0,
1632 					PHYDSYMCLK_SRC_SEL, 0);
1633 		}
1634 		break;
1635 	case 4:
1636 		if (force_enable) {
1637 			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
1638 					PHYESYMCLK_EN, 1,
1639 					PHYESYMCLK_SRC_SEL, clk_src);
1640 		} else {
1641 			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
1642 					PHYESYMCLK_EN, 0,
1643 					PHYESYMCLK_SRC_SEL, 0);
1644 		}
1645 		break;
1646 	default:
1647 		BREAK_TO_DEBUGGER();
1648 		return;
1649 	}
1650 	DC_LOG_DEBUG("%s: phy_inst(%d) PHYxSYMCLK_EN = %d, PHYxSYMCLK_SRC_SEL = %d\n",
1651 			__func__, phy_inst, force_enable ? 1 : 0, clk_src);
1652 }
1653 
1654 static void dccg35_set_valid_pixel_rate(
1655 		struct dccg *dccg,
1656 		int ref_dtbclk_khz,
1657 		int otg_inst,
1658 		int pixclk_khz)
1659 {
1660 	struct dtbclk_dto_params dto_params = {0};
1661 
1662 	dto_params.ref_dtbclk_khz = ref_dtbclk_khz;
1663 	dto_params.otg_inst = otg_inst;
1664 	dto_params.pixclk_khz = pixclk_khz;
1665 	dto_params.is_hdmi = true;
1666 
1667 	dccg35_set_dtbclk_dto(dccg, &dto_params);
1668 }
1669 
1670 void dccg35_dpp_root_clock_control(struct dccg *dccg, unsigned int dpp_inst, bool clock_on)
1671 {
1672 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1673 
1674 	if (dccg->dpp_clock_gated[dpp_inst] != clock_on)
1675 		return;
1676 
1677 	if (clock_on) {
1678 		dccg35_set_dppclk_rcg(dccg, dpp_inst, false);
1679 
1680 		/* turn off the DTO and leave phase/modulo at max */
1681 		dcn35_set_dppclk_enable(dccg, dpp_inst, 1);
1682 		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
1683 			  DPPCLK0_DTO_PHASE, 0xFF,
1684 			  DPPCLK0_DTO_MODULO, 0xFF);
1685 	} else {
1686 		dcn35_set_dppclk_enable(dccg, dpp_inst, 0);
1687 		/* turn on the DTO to generate a 0hz clock */
1688 		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
1689 			  DPPCLK0_DTO_PHASE, 0,
1690 			  DPPCLK0_DTO_MODULO, 1);
1691 		/*we have this in hwss: disable_plane*/
1692 		dccg35_set_dppclk_rcg(dccg, dpp_inst, true);
1693 	}
1694 
1695 	// wait for clock to fully ramp
1696 	udelay(10);
1697 
1698 	dccg->dpp_clock_gated[dpp_inst] = !clock_on;
1699 	DC_LOG_DEBUG("%s: dpp_inst(%d) clock_on = %d\n", __func__, dpp_inst, clock_on);
1700 }
1701 
1702 void dccg35_disable_symclk32_se(struct dccg *dccg, int hpo_se_inst)
1703 {
1704 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1705 
1706 	/* set refclk as the source for symclk32_se */
1707 	switch (hpo_se_inst) {
1708 	case 0:
1709 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
1710 				SYMCLK32_SE0_SRC_SEL, 0,
1711 				SYMCLK32_SE0_EN, 0);
1712 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {
1713 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1714 					SYMCLK32_SE0_GATE_DISABLE, 0);
1715 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1716 //					SYMCLK32_ROOT_SE0_GATE_DISABLE, 0);
1717 		}
1718 		break;
1719 	case 1:
1720 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
1721 				SYMCLK32_SE1_SRC_SEL, 0,
1722 				SYMCLK32_SE1_EN, 0);
1723 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {
1724 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1725 					SYMCLK32_SE1_GATE_DISABLE, 0);
1726 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1727 //					SYMCLK32_ROOT_SE1_GATE_DISABLE, 0);
1728 		}
1729 		break;
1730 	case 2:
1731 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
1732 				SYMCLK32_SE2_SRC_SEL, 0,
1733 				SYMCLK32_SE2_EN, 0);
1734 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {
1735 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1736 					SYMCLK32_SE2_GATE_DISABLE, 0);
1737 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1738 //					SYMCLK32_ROOT_SE2_GATE_DISABLE, 0);
1739 		}
1740 		break;
1741 	case 3:
1742 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
1743 				SYMCLK32_SE3_SRC_SEL, 0,
1744 				SYMCLK32_SE3_EN, 0);
1745 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {
1746 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1747 					SYMCLK32_SE3_GATE_DISABLE, 0);
1748 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1749 //					SYMCLK32_ROOT_SE3_GATE_DISABLE, 0);
1750 		}
1751 		break;
1752 	default:
1753 		BREAK_TO_DEBUGGER();
1754 		return;
1755 	}
1756 
1757 }
1758 
1759 static void dccg35_init_cb(struct dccg *dccg)
1760 {
1761 	(void)dccg;
1762 	/* Any RCG should be done when driver enter low power mode*/
1763 }
1764 void dccg35_init(struct dccg *dccg)
1765 {
1766 	int otg_inst;
1767 	/* Set HPO stream encoder to use refclk to avoid case where PHY is
1768 	 * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which
1769 	 * will cause DCN to hang.
1770 	 */
1771 	for (otg_inst = 0; otg_inst < 4; otg_inst++)
1772 		dccg35_disable_symclk32_se(dccg, otg_inst);
1773 
1774 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
1775 		for (otg_inst = 0; otg_inst < 2; otg_inst++) {
1776 			dccg31_disable_symclk32_le(dccg, otg_inst);
1777 			dccg31_set_symclk32_le_root_clock_gating(dccg, otg_inst, false);
1778 			DC_LOG_DEBUG("%s: OTG%d SYMCLK32_LE disabled and root clock gating disabled\n",
1779 					__func__, otg_inst);
1780 		}
1781 
1782 //	if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1783 //		for (otg_inst = 0; otg_inst < 4; otg_inst++)
1784 //			dccg35_disable_symclk_se(dccg, otg_inst, otg_inst);
1785 
1786 
1787 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1788 		for (otg_inst = 0; otg_inst < 4; otg_inst++) {
1789 			dccg35_set_dpstreamclk(dccg, REFCLK, otg_inst,
1790 						otg_inst);
1791 			dccg35_set_dpstreamclk_root_clock_gating(dccg, otg_inst, false);
1792 			DC_LOG_DEBUG("%s: OTG%d DPSTREAMCLK disabled and root clock gating disabled\n",
1793 					__func__, otg_inst);
1794 		}
1795 
1796 /*
1797 	dccg35_enable_global_fgcg_rep(
1798 		dccg, dccg->ctx->dc->debug.enable_fine_grain_clock_gating.bits
1799 			      .dccg_global_fgcg_rep);*/
1800 }
1801 
1802 void dccg35_enable_global_fgcg_rep(struct dccg *dccg, bool value)
1803 {
1804 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1805 
1806 	REG_UPDATE(DCCG_GLOBAL_FGCG_REP_CNTL, DCCG_GLOBAL_FGCG_REP_DIS, !value);
1807 }
1808 
1809 void dccg35_enable_dscclk(struct dccg *dccg, int inst)
1810 {
1811 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1812 
1813 	//Disable DTO
1814 	switch (inst) {
1815 	case 0:
1816 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, 1);
1817 
1818 		REG_UPDATE_2(DSCCLK0_DTO_PARAM,
1819 				DSCCLK0_DTO_PHASE, 0,
1820 				DSCCLK0_DTO_MODULO, 0);
1821 		REG_UPDATE(DSCCLK_DTO_CTRL,	DSCCLK0_EN, 1);
1822 		break;
1823 	case 1:
1824 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, 1);
1825 
1826 		REG_UPDATE_2(DSCCLK1_DTO_PARAM,
1827 				DSCCLK1_DTO_PHASE, 0,
1828 				DSCCLK1_DTO_MODULO, 0);
1829 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 1);
1830 		break;
1831 	case 2:
1832 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, 1);
1833 
1834 		REG_UPDATE_2(DSCCLK2_DTO_PARAM,
1835 				DSCCLK2_DTO_PHASE, 0,
1836 				DSCCLK2_DTO_MODULO, 0);
1837 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 1);
1838 		break;
1839 	case 3:
1840 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, 1);
1841 
1842 		REG_UPDATE_2(DSCCLK3_DTO_PARAM,
1843 				DSCCLK3_DTO_PHASE, 0,
1844 				DSCCLK3_DTO_MODULO, 0);
1845 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, 1);
1846 		break;
1847 	default:
1848 		BREAK_TO_DEBUGGER();
1849 		return;
1850 	}
1851 
1852 	/* Wait for clock to ramp */
1853 	udelay(10);
1854 }
1855 
1856 void dccg35_disable_dscclk(struct dccg *dccg, int inst)
1857 {
1858 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1859 
1860 	switch (inst) {
1861 	case 0:
1862 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, 0);
1863 		REG_UPDATE_2(DSCCLK0_DTO_PARAM,
1864 				DSCCLK0_DTO_PHASE, 0,
1865 				DSCCLK0_DTO_MODULO, 1);
1866 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1867 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, 0);
1868 		break;
1869 	case 1:
1870 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 0);
1871 		REG_UPDATE_2(DSCCLK1_DTO_PARAM,
1872 				DSCCLK1_DTO_PHASE, 0,
1873 				DSCCLK1_DTO_MODULO, 1);
1874 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1875 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, 0);
1876 		break;
1877 	case 2:
1878 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 0);
1879 		REG_UPDATE_2(DSCCLK2_DTO_PARAM,
1880 				DSCCLK2_DTO_PHASE, 0,
1881 				DSCCLK2_DTO_MODULO, 1);
1882 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1883 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, 0);
1884 		break;
1885 	case 3:
1886 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, 0);
1887 		REG_UPDATE_2(DSCCLK3_DTO_PARAM,
1888 				DSCCLK3_DTO_PHASE, 0,
1889 				DSCCLK3_DTO_MODULO, 1);
1890 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1891 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, 0);
1892 		break;
1893 	default:
1894 		return;
1895 	}
1896 
1897 	/* Wait for clock ramp */
1898 	udelay(10);
1899 }
1900 
1901 void dccg35_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
1902 {
1903 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1904 
1905 	switch (link_enc_inst) {
1906 	case 0:
1907 		REG_UPDATE(SYMCLKA_CLOCK_ENABLE,
1908 				SYMCLKA_CLOCK_ENABLE, 1);
1909 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1910 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_ROOT_GATE_DISABLE, 1);
1911 		break;
1912 	case 1:
1913 		REG_UPDATE(SYMCLKB_CLOCK_ENABLE,
1914 				SYMCLKB_CLOCK_ENABLE, 1);
1915 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1916 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_ROOT_GATE_DISABLE, 1);
1917 		break;
1918 	case 2:
1919 		REG_UPDATE(SYMCLKC_CLOCK_ENABLE,
1920 				SYMCLKC_CLOCK_ENABLE, 1);
1921 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1922 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_ROOT_GATE_DISABLE, 1);
1923 		break;
1924 	case 3:
1925 		REG_UPDATE(SYMCLKD_CLOCK_ENABLE,
1926 				SYMCLKD_CLOCK_ENABLE, 1);
1927 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1928 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_ROOT_GATE_DISABLE, 1);
1929 		break;
1930 	case 4:
1931 		REG_UPDATE(SYMCLKE_CLOCK_ENABLE,
1932 				SYMCLKE_CLOCK_ENABLE, 1);
1933 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1934 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_ROOT_GATE_DISABLE, 1);
1935 		break;
1936 	}
1937 
1938 	switch (stream_enc_inst) {
1939 	case 0:
1940 		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,
1941 				SYMCLKA_FE_EN, 1,
1942 				SYMCLKA_FE_SRC_SEL, link_enc_inst);
1943 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1944 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_FE_ROOT_GATE_DISABLE, 1);
1945 		break;
1946 	case 1:
1947 		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,
1948 				SYMCLKB_FE_EN, 1,
1949 				SYMCLKB_FE_SRC_SEL, link_enc_inst);
1950 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1951 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_FE_ROOT_GATE_DISABLE, 1);
1952 		break;
1953 	case 2:
1954 		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,
1955 				SYMCLKC_FE_EN, 1,
1956 				SYMCLKC_FE_SRC_SEL, link_enc_inst);
1957 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1958 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_FE_ROOT_GATE_DISABLE, 1);
1959 		break;
1960 	case 3:
1961 		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,
1962 				SYMCLKD_FE_EN, 1,
1963 				SYMCLKD_FE_SRC_SEL, link_enc_inst);
1964 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1965 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_FE_ROOT_GATE_DISABLE, 1);
1966 		break;
1967 	case 4:
1968 		REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,
1969 				SYMCLKE_FE_EN, 1,
1970 				SYMCLKE_FE_SRC_SEL, link_enc_inst);
1971 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1972 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_FE_ROOT_GATE_DISABLE, 1);
1973 		break;
1974 	}
1975 }
1976 
1977 /*get other front end connected to this backend*/
1978 static uint8_t dccg35_get_number_enabled_symclk_fe_connected_to_be(struct dccg *dccg, uint32_t link_enc_inst)
1979 {
1980 	uint8_t num_enabled_symclk_fe = 0;
1981 	uint32_t fe_clk_en[5] = {0}, be_clk_sel[5] = {0};
1982 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1983 
1984 	REG_GET_2(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_EN, &fe_clk_en[0],
1985 		SYMCLKA_FE_SRC_SEL, &be_clk_sel[0]);
1986 
1987 	REG_GET_2(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_EN, &fe_clk_en[1],
1988 		SYMCLKB_FE_SRC_SEL, &be_clk_sel[1]);
1989 
1990 	REG_GET_2(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_EN, &fe_clk_en[2],
1991 		SYMCLKC_FE_SRC_SEL, &be_clk_sel[2]);
1992 
1993 	REG_GET_2(SYMCLKD_CLOCK_ENABLE,	SYMCLKD_FE_EN, &fe_clk_en[3],
1994 		SYMCLKD_FE_SRC_SEL, &be_clk_sel[3]);
1995 
1996 	REG_GET_2(SYMCLKE_CLOCK_ENABLE,	SYMCLKE_FE_EN, &fe_clk_en[4],
1997 		SYMCLKE_FE_SRC_SEL, &be_clk_sel[4]);
1998 
1999 	uint8_t i;
2000 
2001 	for (i = 0; i < ARRAY_SIZE(fe_clk_en); i++) {
2002 		if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst)
2003 			num_enabled_symclk_fe++;
2004 	}
2005 	return num_enabled_symclk_fe;
2006 }
2007 
2008 void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
2009 {
2010 	uint8_t num_enabled_symclk_fe = 0;
2011 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
2012 
2013 	switch (stream_enc_inst) {
2014 	case 0:
2015 		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,
2016 				SYMCLKA_FE_EN, 0,
2017 				SYMCLKA_FE_SRC_SEL, 0);
2018 //		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2019 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_FE_ROOT_GATE_DISABLE, 0);
2020 		break;
2021 	case 1:
2022 		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,
2023 				SYMCLKB_FE_EN, 0,
2024 				SYMCLKB_FE_SRC_SEL, 0);
2025 //		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2026 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_FE_ROOT_GATE_DISABLE, 0);
2027 		break;
2028 	case 2:
2029 		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,
2030 				SYMCLKC_FE_EN, 0,
2031 				SYMCLKC_FE_SRC_SEL, 0);
2032 //		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2033 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_FE_ROOT_GATE_DISABLE, 0);
2034 		break;
2035 	case 3:
2036 		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,
2037 				SYMCLKD_FE_EN, 0,
2038 				SYMCLKD_FE_SRC_SEL, 0);
2039 //		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2040 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_FE_ROOT_GATE_DISABLE, 0);
2041 		break;
2042 	case 4:
2043 		REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,
2044 				SYMCLKE_FE_EN, 0,
2045 				SYMCLKE_FE_SRC_SEL, 0);
2046 //		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2047 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_FE_ROOT_GATE_DISABLE, 0);
2048 		break;
2049 	}
2050 
2051 	/*check other enabled symclk fe connected to this be */
2052 	num_enabled_symclk_fe = dccg35_get_number_enabled_symclk_fe_connected_to_be(dccg, link_enc_inst);
2053 	/*only turn off backend clk if other front end attached to this backend are all off,
2054 	 for mst, only turn off the backend if this is the last front end*/
2055 	if (num_enabled_symclk_fe == 0) {
2056 		switch (link_enc_inst) {
2057 		case 0:
2058 			REG_UPDATE(SYMCLKA_CLOCK_ENABLE,
2059 					SYMCLKA_CLOCK_ENABLE, 0);
2060 //			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
2061 //				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_ROOT_GATE_DISABLE, 0);
2062 			break;
2063 		case 1:
2064 			REG_UPDATE(SYMCLKB_CLOCK_ENABLE,
2065 					SYMCLKB_CLOCK_ENABLE, 0);
2066 //			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
2067 //				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_ROOT_GATE_DISABLE, 0);
2068 			break;
2069 		case 2:
2070 			REG_UPDATE(SYMCLKC_CLOCK_ENABLE,
2071 					SYMCLKC_CLOCK_ENABLE, 0);
2072 //			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
2073 //				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_ROOT_GATE_DISABLE, 0);
2074 			break;
2075 		case 3:
2076 			REG_UPDATE(SYMCLKD_CLOCK_ENABLE,
2077 					SYMCLKD_CLOCK_ENABLE, 0);
2078 //			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
2079 //				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_ROOT_GATE_DISABLE, 0);
2080 			break;
2081 		case 4:
2082 			REG_UPDATE(SYMCLKE_CLOCK_ENABLE,
2083 					SYMCLKE_CLOCK_ENABLE, 0);
2084 //			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
2085 //				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_ROOT_GATE_DISABLE, 0);
2086 			break;
2087 		}
2088 	}
2089 }
2090 
2091 static void dccg35_set_dpstreamclk_cb(
2092 		struct dccg *dccg,
2093 		enum streamclk_source src,
2094 		int otg_inst,
2095 		int dp_hpo_inst)
2096 {
2097 
2098 	enum dtbclk_source dtb_clk_src;
2099 	enum dp_stream_clk_source dp_stream_clk_src;
2100 
2101 	switch (src) {
2102 	case REFCLK:
2103 		dtb_clk_src = DTBCLK_REFCLK;
2104 		dp_stream_clk_src = DP_STREAM_REFCLK;
2105 		break;
2106 	case DPREFCLK:
2107 		dtb_clk_src = DTBCLK_DPREFCLK;
2108 		dp_stream_clk_src = (enum dp_stream_clk_source)otg_inst;
2109 		break;
2110 	case DTBCLK0:
2111 		dtb_clk_src = DTBCLK_DTBCLK0;
2112 		dp_stream_clk_src = (enum dp_stream_clk_source)otg_inst;
2113 		break;
2114 	default:
2115 		BREAK_TO_DEBUGGER();
2116 		return;
2117 	}
2118 
2119 	if (dtb_clk_src == DTBCLK_REFCLK &&
2120 		dp_stream_clk_src == DP_STREAM_REFCLK) {
2121 		dccg35_disable_dtbclk_p_new(dccg, otg_inst);
2122 		dccg35_disable_dpstreamclk_new(dccg, dp_hpo_inst);
2123 	} else {
2124 		dccg35_enable_dtbclk_p_new(dccg, dtb_clk_src, otg_inst);
2125 		dccg35_enable_dpstreamclk_new(dccg,
2126 										dp_stream_clk_src,
2127 										dp_hpo_inst);
2128 	}
2129 }
2130 
2131 static void dccg35_set_dpstreamclk_root_clock_gating_cb(
2132 	struct dccg *dccg,
2133 	int dp_hpo_inst,
2134 	bool power_on)
2135 {
2136 	/* power_on set indicates we need to ungate
2137 	 * Currently called from optimize_bandwidth and prepare_bandwidth calls
2138 	 * Since clock source is not passed restore to refclock on ungate
2139 	 * Instance 0 is implied here since only one streamclock resource
2140 	 * Redundant as gating when enabled is acheived through set_dpstreamclk
2141 	 */
2142 	if (power_on)
2143 		dccg35_enable_dpstreamclk_new(dccg,
2144 										DP_STREAM_REFCLK,
2145 										dp_hpo_inst);
2146 	else
2147 		dccg35_disable_dpstreamclk_new(dccg, dp_hpo_inst);
2148 }
2149 
2150 static void dccg35_update_dpp_dto_cb(struct dccg *dccg, int dpp_inst,
2151 				  int req_dppclk)
2152 {
2153 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
2154 
2155 	if (dccg->dpp_clock_gated[dpp_inst]) {
2156 		/*
2157 		 * Do not update the DPPCLK DTO if the clock is stopped.
2158 		 */
2159 		return;
2160 	}
2161 
2162 	if (dccg->ref_dppclk && req_dppclk) {
2163 		int ref_dppclk = dccg->ref_dppclk;
2164 		int modulo, phase;
2165 
2166 		// phase / modulo = dpp pipe clk / dpp global clk
2167 		modulo = 0xff;   // use FF at the end
2168 		phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;
2169 
2170 		if (phase > 0xff) {
2171 			ASSERT(false);
2172 			phase = 0xff;
2173 		}
2174 
2175 		/* Enable DPP CLK DTO output */
2176 		dccg35_enable_dpp_clk_new(dccg, dpp_inst, DPP_DCCG_DTO);
2177 
2178 		/* Program DTO */
2179 		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
2180 				DPPCLK0_DTO_PHASE, phase,
2181 				DPPCLK0_DTO_MODULO, modulo);
2182 	} else
2183 		dccg35_disable_dpp_clk_new(dccg, dpp_inst);
2184 
2185 	dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
2186 }
2187 
2188 static void dccg35_dpp_root_clock_control_cb(
2189 	struct dccg *dccg,
2190 	unsigned int dpp_inst,
2191 	bool power_on)
2192 {
2193 	if (dccg->dpp_clock_gated[dpp_inst] == power_on)
2194 		return;
2195 	/* power_on set indicates we need to ungate
2196 	 * Currently called from optimize_bandwidth and prepare_bandwidth calls
2197 	 * Since clock source is not passed restore to refclock on ungate
2198 	 * Redundant as gating when enabled is acheived through update_dpp_dto
2199 	 */
2200 	dccg35_set_dppclk_rcg(dccg, dpp_inst, !power_on);
2201 
2202 	dccg->dpp_clock_gated[dpp_inst] = !power_on;
2203 }
2204 
2205 static void dccg35_enable_symclk32_se_cb(
2206 	struct dccg *dccg,
2207 	int inst,
2208 	enum phyd32clk_clock_source phyd32clk)
2209 {
2210 	dccg35_enable_symclk32_se_new(dccg, inst, (enum symclk32_se_clk_source)phyd32clk);
2211 }
2212 
2213 static void dccg35_disable_symclk32_se_cb(struct dccg *dccg, int inst)
2214 {
2215 	dccg35_disable_symclk32_se_new(dccg, inst);
2216 }
2217 
2218 static void dccg35_enable_symclk32_le_cb(
2219 			struct dccg *dccg,
2220 			int inst,
2221 			enum phyd32clk_clock_source src)
2222 {
2223 	dccg35_enable_symclk32_le_new(dccg, inst, (enum symclk32_le_clk_source) src);
2224 }
2225 
2226 static void dccg35_disable_symclk32_le_cb(struct dccg *dccg, int inst)
2227 {
2228 	dccg35_disable_symclk32_le_new(dccg, inst);
2229 }
2230 
2231 static void dccg35_set_symclk32_le_root_clock_gating_cb(
2232 	struct dccg *dccg,
2233 	int inst,
2234 	bool power_on)
2235 {
2236 	/* power_on set indicates we need to ungate
2237 	 * Currently called from optimize_bandwidth and prepare_bandwidth calls
2238 	 * Since clock source is not passed restore to refclock on ungate
2239 	 * Redundant as gating when enabled is acheived through disable_symclk32_le
2240 	 */
2241 	if (power_on)
2242 		dccg35_enable_symclk32_le_new(dccg, inst, SYMCLK32_LE_REFCLK);
2243 	else
2244 		dccg35_disable_symclk32_le_new(dccg, inst);
2245 }
2246 
2247 static void dccg35_set_physymclk_cb(
2248 	struct dccg *dccg,
2249 	int inst,
2250 	enum physymclk_clock_source clk_src,
2251 	bool force_enable)
2252 {
2253 	/* force_enable = 0 indicates we can switch to ref clock */
2254 	if (force_enable)
2255 		dccg35_enable_physymclk_new(dccg, inst, (enum physymclk_source)clk_src);
2256 	else
2257 		dccg35_disable_physymclk_new(dccg, inst);
2258 }
2259 
2260 static void dccg35_set_physymclk_root_clock_gating_cb(
2261 	struct dccg *dccg,
2262 	int inst,
2263 	bool power_on)
2264 {
2265 	/* Redundant RCG already done in disable_physymclk
2266 	 * power_on = 1 indicates we need to ungate
2267 	 */
2268 	if (power_on)
2269 		dccg35_enable_physymclk_new(dccg, inst, PHYSYMCLK_REFCLK);
2270 	else
2271 		dccg35_disable_physymclk_new(dccg, inst);
2272 }
2273 
2274 static void dccg35_set_symclk32_le_root_clock_gating(
2275 	struct dccg *dccg,
2276 	int inst,
2277 	bool power_on)
2278 {
2279 	/* power_on set indicates we need to ungate
2280 	 * Currently called from optimize_bandwidth and prepare_bandwidth calls
2281 	 * Since clock source is not passed restore to refclock on ungate
2282 	 * Redundant as gating when enabled is acheived through disable_symclk32_le
2283 	 */
2284 	if (power_on)
2285 		dccg35_enable_symclk32_le_new(dccg, inst, SYMCLK32_LE_REFCLK);
2286 	else
2287 		dccg35_disable_symclk32_le_new(dccg, inst);
2288 }
2289 
2290 static void dccg35_set_dtbclk_p_src_cb(
2291 		struct dccg *dccg,
2292 		enum streamclk_source src,
2293 		uint32_t inst)
2294 {
2295 	if (src == DTBCLK0)
2296 		dccg35_enable_dtbclk_p_new(dccg, DTBCLK_DTBCLK0, inst);
2297 	else
2298 		dccg35_disable_dtbclk_p_new(dccg, inst);
2299 }
2300 
2301 static void dccg35_set_dtbclk_dto_cb(
2302 		struct dccg *dccg,
2303 		const struct dtbclk_dto_params *params)
2304 {
2305 	/* set_dtbclk_p_src typ called earlier to switch to DTBCLK
2306 	 * if params->ref_dtbclk_khz and req_dtbclk_khz are 0 switch to ref-clock
2307 	 */
2308 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
2309 	/* DTO Output Rate / Pixel Rate = 1/4 */
2310 	int req_dtbclk_khz = params->pixclk_khz / 4;
2311 
2312 	if (params->ref_dtbclk_khz && req_dtbclk_khz) {
2313 		uint32_t modulo, phase;
2314 
2315 		dccg35_enable_dtbclk_p_new(dccg, DTBCLK_DTBCLK0, params->otg_inst);
2316 
2317 		// phase / modulo = dtbclk / dtbclk ref
2318 		modulo = params->ref_dtbclk_khz * 1000;
2319 		phase = req_dtbclk_khz * 1000;
2320 
2321 		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
2322 		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
2323 
2324 		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
2325 				DTBCLK_DTO_ENABLE[params->otg_inst], 1);
2326 
2327 		REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
2328 				DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
2329 				1, 100);
2330 
2331 		/* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */
2332 		dccg35_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
2333 
2334 		/* The recommended programming sequence to enable DTBCLK DTO to generate
2335 		 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
2336 		 * be set only after DTO is enabled
2337 		 */
2338 		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
2339 				PIPE_DTO_SRC_SEL[params->otg_inst], 2);
2340 	} else {
2341 		dccg35_disable_dtbclk_p_new(dccg, params->otg_inst);
2342 
2343 		REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
2344 					 DTBCLK_DTO_ENABLE[params->otg_inst], 0,
2345 					 PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1);
2346 
2347 		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
2348 		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
2349 	}
2350 }
2351 
2352 static void dccg35_disable_dscclk_cb(struct dccg *dccg,
2353 									 int inst)
2354 {
2355 	dccg35_disable_dscclk_new(dccg, inst);
2356 }
2357 
2358 static void dccg35_enable_dscclk_cb(struct dccg *dccg, int inst)
2359 {
2360 	dccg35_enable_dscclk_new(dccg, inst, DSC_DTO_TUNED_CK_GPU_DISCLK_3);
2361 }
2362 
2363 static void dccg35_enable_symclk_se_cb(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
2364 {
2365 	/* Switch to functional clock if already not selected */
2366 	dccg35_enable_symclk_be_new(dccg, SYMCLK_BE_PHYCLK, link_enc_inst);
2367 
2368 	dccg35_enable_symclk_fe_new(dccg, stream_enc_inst, (enum symclk_fe_source) link_enc_inst);
2369 
2370 }
2371 
2372 static void dccg35_disable_symclk_se_cb(
2373 			struct dccg *dccg,
2374 			uint32_t stream_enc_inst,
2375 			uint32_t link_enc_inst)
2376 {
2377 	(void)link_enc_inst;
2378 	dccg35_disable_symclk_fe_new(dccg, stream_enc_inst);
2379 
2380 	/* DMU PHY sequence switches SYMCLK_BE (link_enc_inst) to ref clock once PHY is turned off */
2381 }
2382 
2383 void dccg35_root_gate_disable_control(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating)
2384 {
2385 	dccg35_set_dppclk_root_clock_gating(dccg, pipe_idx, disable_clock_gating);
2386 }
2387 
2388 static const struct dccg_funcs dccg35_funcs_new = {
2389 	.update_dpp_dto = dccg35_update_dpp_dto_cb,
2390 	.dpp_root_clock_control = dccg35_dpp_root_clock_control_cb,
2391 	.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
2392 	.dccg_init = dccg35_init_cb,
2393 	.set_dpstreamclk = dccg35_set_dpstreamclk_cb,
2394 	.set_dpstreamclk_root_clock_gating = dccg35_set_dpstreamclk_root_clock_gating_cb,
2395 	.enable_symclk32_se = dccg35_enable_symclk32_se_cb,
2396 	.disable_symclk32_se = dccg35_disable_symclk32_se_cb,
2397 	.enable_symclk32_le = dccg35_enable_symclk32_le_cb,
2398 	.disable_symclk32_le = dccg35_disable_symclk32_le_cb,
2399 	.set_symclk32_le_root_clock_gating = dccg35_set_symclk32_le_root_clock_gating_cb,
2400 	.set_physymclk = dccg35_set_physymclk_cb,
2401 	.set_physymclk_root_clock_gating = dccg35_set_physymclk_root_clock_gating_cb,
2402 	.set_dtbclk_dto = dccg35_set_dtbclk_dto_cb,
2403 	.set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
2404 	.set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
2405 	.otg_add_pixel = dccg31_otg_add_pixel,
2406 	.otg_drop_pixel = dccg31_otg_drop_pixel,
2407 	.set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
2408 	.disable_dsc = dccg35_disable_dscclk_cb,
2409 	.enable_dsc = dccg35_enable_dscclk_cb,
2410 	.set_pixel_rate_div = dccg35_set_pixel_rate_div,
2411 	.get_pixel_rate_div = dccg35_get_pixel_rate_div,
2412 	.trigger_dio_fifo_resync = dccg35_trigger_dio_fifo_resync,
2413 	.set_valid_pixel_rate = dccg35_set_valid_pixel_rate,
2414 	.enable_symclk_se = dccg35_enable_symclk_se_cb,
2415 	.disable_symclk_se = dccg35_disable_symclk_se_cb,
2416 	.set_dtbclk_p_src = dccg35_set_dtbclk_p_src_cb,
2417 	.refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */
2418 	.allow_clock_gating = dccg2_allow_clock_gating,
2419 	.enable_memory_low_power = dccg2_enable_memory_low_power,
2420 	.is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */
2421 };
2422 
2423 static const struct dccg_funcs dccg35_funcs = {
2424 	.update_dpp_dto = dccg35_update_dpp_dto,
2425 	.dpp_root_clock_control = dccg35_dpp_root_clock_control,
2426 	.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
2427 	.dccg_init = dccg35_init,
2428 	.set_dpstreamclk = dccg35_set_dpstreamclk,
2429 	.set_dpstreamclk_root_clock_gating = dccg35_set_dpstreamclk_root_clock_gating,
2430 	.enable_symclk32_se = dccg31_enable_symclk32_se,
2431 	.disable_symclk32_se = dccg35_disable_symclk32_se,
2432 	.enable_symclk32_le = dccg31_enable_symclk32_le,
2433 	.disable_symclk32_le = dccg31_disable_symclk32_le,
2434 	.set_symclk32_le_root_clock_gating = dccg31_set_symclk32_le_root_clock_gating,
2435 	.set_physymclk = dccg35_set_physymclk,
2436 	.set_physymclk_root_clock_gating = dccg35_set_physymclk_root_clock_gating,
2437 	.set_dtbclk_dto = dccg35_set_dtbclk_dto,
2438 	.set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
2439 	.set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
2440 	.otg_add_pixel = dccg31_otg_add_pixel,
2441 	.otg_drop_pixel = dccg31_otg_drop_pixel,
2442 	.set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
2443 	.disable_dsc = dccg35_disable_dscclk,
2444 	.enable_dsc = dccg35_enable_dscclk,
2445 	.set_pixel_rate_div = dccg35_set_pixel_rate_div,
2446 	.get_pixel_rate_div = dccg35_get_pixel_rate_div,
2447 	.trigger_dio_fifo_resync = dccg35_trigger_dio_fifo_resync,
2448 	.set_valid_pixel_rate = dccg35_set_valid_pixel_rate,
2449 	.enable_symclk_se = dccg35_enable_symclk_se,
2450 	.disable_symclk_se = dccg35_disable_symclk_se,
2451 	.set_dtbclk_p_src = dccg35_set_dtbclk_p_src,
2452 	.refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */
2453 	.allow_clock_gating = dccg2_allow_clock_gating,
2454 	.enable_memory_low_power = dccg2_enable_memory_low_power,
2455 	.is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done, /* Deprecated - for backward compatibility only */
2456 	.dccg_root_gate_disable_control = dccg35_root_gate_disable_control,
2457 	.dccg_read_reg_state = dccg31_read_reg_state
2458 };
2459 
2460 struct dccg *dccg35_create(
2461 	struct dc_context *ctx,
2462 	const struct dccg_registers *regs,
2463 	const struct dccg_shift *dccg_shift,
2464 	const struct dccg_mask *dccg_mask)
2465 {
2466 	struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn);
2467 	struct dccg *base;
2468 
2469 	if (dccg_dcn == NULL) {
2470 		BREAK_TO_DEBUGGER();
2471 		return NULL;
2472 	}
2473 	(void)&dccg35_disable_symclk_be_new;
2474 	(void)&dccg35_set_symclk32_le_root_clock_gating;
2475 	(void)&dccg35_set_smclk32_se_rcg;
2476 	(void)&dccg35_funcs_new;
2477 
2478 	base = &dccg_dcn->base;
2479 	base->ctx = ctx;
2480 	base->funcs = &dccg35_funcs;
2481 
2482 	dccg_dcn->regs = regs;
2483 	dccg_dcn->dccg_shift = dccg_shift;
2484 	dccg_dcn->dccg_mask = dccg_mask;
2485 
2486 	return &dccg_dcn->base;
2487 }
2488