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