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 		 */
1397 		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
1398 				PIPE_DTO_SRC_SEL[params->otg_inst], 2);
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 		REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
1416 				DTBCLK_DTO_ENABLE[params->otg_inst], 0,
1417 				PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1);
1418 
1419 		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
1420 		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
1421 	}
1422 }
1423 
dccg35_set_dpstreamclk(struct dccg * dccg,enum streamclk_source src,int otg_inst,int dp_hpo_inst)1424 static void dccg35_set_dpstreamclk(
1425 		struct dccg *dccg,
1426 		enum streamclk_source src,
1427 		int otg_inst,
1428 		int dp_hpo_inst)
1429 {
1430 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1431 
1432 	/* set the dtbclk_p source */
1433 	dccg35_set_dtbclk_p_src(dccg, src, otg_inst);
1434 
1435 	/* enabled to select one of the DTBCLKs for pipe */
1436 	switch (dp_hpo_inst) {
1437 	case 0:
1438 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK0_EN,
1439 				(src == REFCLK) ? 0 : 1, DPSTREAMCLK0_SRC_SEL, otg_inst);
1440 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1441 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);
1442 		break;
1443 	case 1:
1444 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK1_EN,
1445 				(src == REFCLK) ? 0 : 1, DPSTREAMCLK1_SRC_SEL, otg_inst);
1446 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1447 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);
1448 		break;
1449 	case 2:
1450 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK2_EN,
1451 				(src == REFCLK) ? 0 : 1, DPSTREAMCLK2_SRC_SEL, otg_inst);
1452 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1453 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);
1454 		break;
1455 	case 3:
1456 		REG_UPDATE_2(DPSTREAMCLK_CNTL, DPSTREAMCLK3_EN,
1457 				(src == REFCLK) ? 0 : 1, DPSTREAMCLK3_SRC_SEL, otg_inst);
1458 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1459 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_ROOT_GATE_DISABLE, (src == REFCLK) ? 0 : 1);
1460 		break;
1461 	default:
1462 		BREAK_TO_DEBUGGER();
1463 		return;
1464 	}
1465 }
1466 
1467 
dccg35_set_dpstreamclk_root_clock_gating(struct dccg * dccg,int dp_hpo_inst,bool enable)1468 static void dccg35_set_dpstreamclk_root_clock_gating(
1469 		struct dccg *dccg,
1470 		int dp_hpo_inst,
1471 		bool enable)
1472 {
1473 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1474 
1475 	switch (dp_hpo_inst) {
1476 	case 0:
1477 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
1478 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_ROOT_GATE_DISABLE, enable ? 1 : 0);
1479 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK0_GATE_DISABLE, enable ? 1 : 0);
1480 		}
1481 		break;
1482 	case 1:
1483 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
1484 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_ROOT_GATE_DISABLE, enable ? 1 : 0);
1485 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK1_GATE_DISABLE, enable ? 1 : 0);
1486 		}
1487 		break;
1488 	case 2:
1489 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
1490 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_ROOT_GATE_DISABLE, enable ? 1 : 0);
1491 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK2_GATE_DISABLE, enable ? 1 : 0);
1492 		}
1493 		break;
1494 	case 3:
1495 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
1496 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_ROOT_GATE_DISABLE, enable ? 1 : 0);
1497 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DPSTREAMCLK3_GATE_DISABLE, enable ? 1 : 0);
1498 		}
1499 		break;
1500 	default:
1501 		BREAK_TO_DEBUGGER();
1502 		return;
1503 	}
1504 }
1505 
1506 
1507 
dccg35_set_physymclk_root_clock_gating(struct dccg * dccg,int phy_inst,bool enable)1508 static void dccg35_set_physymclk_root_clock_gating(
1509 		struct dccg *dccg,
1510 		int phy_inst,
1511 		bool enable)
1512 {
1513 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1514 
1515 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
1516 		return;
1517 
1518 	switch (phy_inst) {
1519 	case 0:
1520 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
1521 				PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
1522 		break;
1523 	case 1:
1524 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
1525 				PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
1526 		break;
1527 	case 2:
1528 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
1529 				PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
1530 		break;
1531 	case 3:
1532 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
1533 				PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
1534 		break;
1535 	case 4:
1536 		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
1537 				PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
1538 		break;
1539 	default:
1540 		BREAK_TO_DEBUGGER();
1541 		return;
1542 	}
1543 }
1544 
dccg35_set_physymclk(struct dccg * dccg,int phy_inst,enum physymclk_clock_source clk_src,bool force_enable)1545 static void dccg35_set_physymclk(
1546 		struct dccg *dccg,
1547 		int phy_inst,
1548 		enum physymclk_clock_source clk_src,
1549 		bool force_enable)
1550 {
1551 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1552 
1553 	/* Force PHYSYMCLK on and Select phyd32clk as the source of clock which is output to PHY through DCIO */
1554 	switch (phy_inst) {
1555 	case 0:
1556 		if (force_enable) {
1557 			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
1558 					PHYASYMCLK_EN, 1,
1559 					PHYASYMCLK_SRC_SEL, clk_src);
1560 		} else {
1561 			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
1562 					PHYASYMCLK_EN, 0,
1563 					PHYASYMCLK_SRC_SEL, 0);
1564 		}
1565 		break;
1566 	case 1:
1567 		if (force_enable) {
1568 			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
1569 					PHYBSYMCLK_EN, 1,
1570 					PHYBSYMCLK_SRC_SEL, clk_src);
1571 		} else {
1572 			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
1573 					PHYBSYMCLK_EN, 0,
1574 					PHYBSYMCLK_SRC_SEL, 0);
1575 		}
1576 		break;
1577 	case 2:
1578 		if (force_enable) {
1579 			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
1580 					PHYCSYMCLK_EN, 1,
1581 					PHYCSYMCLK_SRC_SEL, clk_src);
1582 		} else {
1583 			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
1584 					PHYCSYMCLK_EN, 0,
1585 					PHYCSYMCLK_SRC_SEL, 0);
1586 		}
1587 		break;
1588 	case 3:
1589 		if (force_enable) {
1590 			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
1591 					PHYDSYMCLK_EN, 1,
1592 					PHYDSYMCLK_SRC_SEL, clk_src);
1593 		} else {
1594 			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
1595 					PHYDSYMCLK_EN, 0,
1596 					PHYDSYMCLK_SRC_SEL, 0);
1597 		}
1598 		break;
1599 	case 4:
1600 		if (force_enable) {
1601 			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
1602 					PHYESYMCLK_EN, 1,
1603 					PHYESYMCLK_SRC_SEL, clk_src);
1604 		} else {
1605 			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
1606 					PHYESYMCLK_EN, 0,
1607 					PHYESYMCLK_SRC_SEL, 0);
1608 		}
1609 		break;
1610 	default:
1611 		BREAK_TO_DEBUGGER();
1612 		return;
1613 	}
1614 }
1615 
dccg35_set_valid_pixel_rate(struct dccg * dccg,int ref_dtbclk_khz,int otg_inst,int pixclk_khz)1616 static void dccg35_set_valid_pixel_rate(
1617 		struct dccg *dccg,
1618 		int ref_dtbclk_khz,
1619 		int otg_inst,
1620 		int pixclk_khz)
1621 {
1622 	struct dtbclk_dto_params dto_params = {0};
1623 
1624 	dto_params.ref_dtbclk_khz = ref_dtbclk_khz;
1625 	dto_params.otg_inst = otg_inst;
1626 	dto_params.pixclk_khz = pixclk_khz;
1627 	dto_params.is_hdmi = true;
1628 
1629 	dccg35_set_dtbclk_dto(dccg, &dto_params);
1630 }
1631 
dccg35_dpp_root_clock_control(struct dccg * dccg,unsigned int dpp_inst,bool clock_on)1632 static void dccg35_dpp_root_clock_control(
1633 		struct dccg *dccg,
1634 		unsigned int dpp_inst,
1635 		bool clock_on)
1636 {
1637 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1638 
1639 	if (dccg->dpp_clock_gated[dpp_inst] == clock_on)
1640 		return;
1641 
1642 	if (clock_on) {
1643 		/* turn off the DTO and leave phase/modulo at max */
1644 		dcn35_set_dppclk_enable(dccg, dpp_inst, 1);
1645 		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
1646 			  DPPCLK0_DTO_PHASE, 0xFF,
1647 			  DPPCLK0_DTO_MODULO, 0xFF);
1648 	} else {
1649 		dcn35_set_dppclk_enable(dccg, dpp_inst, 0);
1650 		/* turn on the DTO to generate a 0hz clock */
1651 		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
1652 			  DPPCLK0_DTO_PHASE, 0,
1653 			  DPPCLK0_DTO_MODULO, 1);
1654 	}
1655 
1656 	dccg->dpp_clock_gated[dpp_inst] = !clock_on;
1657 }
1658 
dccg35_disable_symclk32_se(struct dccg * dccg,int hpo_se_inst)1659 static void dccg35_disable_symclk32_se(
1660 		struct dccg *dccg,
1661 		int hpo_se_inst)
1662 {
1663 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1664 
1665 	/* set refclk as the source for symclk32_se */
1666 	switch (hpo_se_inst) {
1667 	case 0:
1668 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
1669 				SYMCLK32_SE0_SRC_SEL, 0,
1670 				SYMCLK32_SE0_EN, 0);
1671 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {
1672 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1673 					SYMCLK32_SE0_GATE_DISABLE, 0);
1674 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1675 //					SYMCLK32_ROOT_SE0_GATE_DISABLE, 0);
1676 		}
1677 		break;
1678 	case 1:
1679 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
1680 				SYMCLK32_SE1_SRC_SEL, 0,
1681 				SYMCLK32_SE1_EN, 0);
1682 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {
1683 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1684 					SYMCLK32_SE1_GATE_DISABLE, 0);
1685 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1686 //					SYMCLK32_ROOT_SE1_GATE_DISABLE, 0);
1687 		}
1688 		break;
1689 	case 2:
1690 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
1691 				SYMCLK32_SE2_SRC_SEL, 0,
1692 				SYMCLK32_SE2_EN, 0);
1693 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {
1694 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1695 					SYMCLK32_SE2_GATE_DISABLE, 0);
1696 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1697 //					SYMCLK32_ROOT_SE2_GATE_DISABLE, 0);
1698 		}
1699 		break;
1700 	case 3:
1701 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
1702 				SYMCLK32_SE3_SRC_SEL, 0,
1703 				SYMCLK32_SE3_EN, 0);
1704 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) {
1705 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1706 					SYMCLK32_SE3_GATE_DISABLE, 0);
1707 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL3,
1708 //					SYMCLK32_ROOT_SE3_GATE_DISABLE, 0);
1709 		}
1710 		break;
1711 	default:
1712 		BREAK_TO_DEBUGGER();
1713 		return;
1714 	}
1715 }
1716 
dccg35_init_cb(struct dccg * dccg)1717 static void dccg35_init_cb(struct dccg *dccg)
1718 {
1719 	(void)dccg;
1720 	/* Any RCG should be done when driver enter low power mode*/
1721 }
1722 
dccg35_init(struct dccg * dccg)1723 void dccg35_init(struct dccg *dccg)
1724 {
1725 	int otg_inst;
1726 	/* Set HPO stream encoder to use refclk to avoid case where PHY is
1727 	 * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which
1728 	 * will cause DCN to hang.
1729 	 */
1730 	for (otg_inst = 0; otg_inst < 4; otg_inst++)
1731 		dccg35_disable_symclk32_se(dccg, otg_inst);
1732 
1733 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
1734 		for (otg_inst = 0; otg_inst < 2; otg_inst++) {
1735 			dccg31_disable_symclk32_le(dccg, otg_inst);
1736 			dccg31_set_symclk32_le_root_clock_gating(dccg, otg_inst, false);
1737 		}
1738 
1739 //	if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1740 //		for (otg_inst = 0; otg_inst < 4; otg_inst++)
1741 //			dccg35_disable_symclk_se(dccg, otg_inst, otg_inst);
1742 
1743 
1744 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
1745 		for (otg_inst = 0; otg_inst < 4; otg_inst++) {
1746 			dccg35_set_dpstreamclk(dccg, REFCLK, otg_inst,
1747 						otg_inst);
1748 			dccg35_set_dpstreamclk_root_clock_gating(dccg, otg_inst, false);
1749 		}
1750 
1751 /*
1752 	dccg35_enable_global_fgcg_rep(
1753 		dccg, dccg->ctx->dc->debug.enable_fine_grain_clock_gating.bits
1754 			      .dccg_global_fgcg_rep);*/
1755 }
1756 
dccg35_enable_global_fgcg_rep(struct dccg * dccg,bool value)1757 void dccg35_enable_global_fgcg_rep(struct dccg *dccg, bool value)
1758 {
1759 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1760 
1761 	REG_UPDATE(DCCG_GLOBAL_FGCG_REP_CNTL, DCCG_GLOBAL_FGCG_REP_DIS, !value);
1762 }
1763 
dccg35_enable_dscclk(struct dccg * dccg,int inst)1764 static void dccg35_enable_dscclk(struct dccg *dccg, int inst)
1765 {
1766 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1767 
1768 	//Disable DTO
1769 	switch (inst) {
1770 	case 0:
1771 		REG_UPDATE_2(DSCCLK0_DTO_PARAM,
1772 				DSCCLK0_DTO_PHASE, 0,
1773 				DSCCLK0_DTO_MODULO, 0);
1774 		REG_UPDATE(DSCCLK_DTO_CTRL,	DSCCLK0_EN, 1);
1775 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1776 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, 1);
1777 		break;
1778 	case 1:
1779 		REG_UPDATE_2(DSCCLK1_DTO_PARAM,
1780 				DSCCLK1_DTO_PHASE, 0,
1781 				DSCCLK1_DTO_MODULO, 0);
1782 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 1);
1783 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1784 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, 1);
1785 		break;
1786 	case 2:
1787 		REG_UPDATE_2(DSCCLK2_DTO_PARAM,
1788 				DSCCLK2_DTO_PHASE, 0,
1789 				DSCCLK2_DTO_MODULO, 0);
1790 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 1);
1791 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1792 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, 1);
1793 		break;
1794 	case 3:
1795 		REG_UPDATE_2(DSCCLK3_DTO_PARAM,
1796 				DSCCLK3_DTO_PHASE, 0,
1797 				DSCCLK3_DTO_MODULO, 0);
1798 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, 1);
1799 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1800 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, 1);
1801 		break;
1802 	default:
1803 		BREAK_TO_DEBUGGER();
1804 		return;
1805 	}
1806 }
1807 
dccg35_disable_dscclk(struct dccg * dccg,int inst)1808 static void dccg35_disable_dscclk(struct dccg *dccg,
1809 				int inst)
1810 {
1811 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1812 
1813 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1814 		return;
1815 
1816 	switch (inst) {
1817 	case 0:
1818 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, 0);
1819 		REG_UPDATE_2(DSCCLK0_DTO_PARAM,
1820 				DSCCLK0_DTO_PHASE, 0,
1821 				DSCCLK0_DTO_MODULO, 1);
1822 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1823 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, 0);
1824 		break;
1825 	case 1:
1826 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 0);
1827 		REG_UPDATE_2(DSCCLK1_DTO_PARAM,
1828 				DSCCLK1_DTO_PHASE, 0,
1829 				DSCCLK1_DTO_MODULO, 1);
1830 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1831 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, 0);
1832 		break;
1833 	case 2:
1834 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 0);
1835 		REG_UPDATE_2(DSCCLK2_DTO_PARAM,
1836 				DSCCLK2_DTO_PHASE, 0,
1837 				DSCCLK2_DTO_MODULO, 1);
1838 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1839 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, 0);
1840 		break;
1841 	case 3:
1842 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, 0);
1843 		REG_UPDATE_2(DSCCLK3_DTO_PARAM,
1844 				DSCCLK3_DTO_PHASE, 0,
1845 				DSCCLK3_DTO_MODULO, 1);
1846 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
1847 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, 0);
1848 		break;
1849 	default:
1850 		return;
1851 	}
1852 }
1853 
dccg35_enable_symclk_se(struct dccg * dccg,uint32_t stream_enc_inst,uint32_t link_enc_inst)1854 static void dccg35_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
1855 {
1856 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1857 
1858 	switch (link_enc_inst) {
1859 	case 0:
1860 		REG_UPDATE(SYMCLKA_CLOCK_ENABLE,
1861 				SYMCLKA_CLOCK_ENABLE, 1);
1862 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1863 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_ROOT_GATE_DISABLE, 1);
1864 		break;
1865 	case 1:
1866 		REG_UPDATE(SYMCLKB_CLOCK_ENABLE,
1867 				SYMCLKB_CLOCK_ENABLE, 1);
1868 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1869 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_ROOT_GATE_DISABLE, 1);
1870 		break;
1871 	case 2:
1872 		REG_UPDATE(SYMCLKC_CLOCK_ENABLE,
1873 				SYMCLKC_CLOCK_ENABLE, 1);
1874 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1875 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_ROOT_GATE_DISABLE, 1);
1876 		break;
1877 	case 3:
1878 		REG_UPDATE(SYMCLKD_CLOCK_ENABLE,
1879 				SYMCLKD_CLOCK_ENABLE, 1);
1880 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1881 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_ROOT_GATE_DISABLE, 1);
1882 		break;
1883 	case 4:
1884 		REG_UPDATE(SYMCLKE_CLOCK_ENABLE,
1885 				SYMCLKE_CLOCK_ENABLE, 1);
1886 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1887 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_ROOT_GATE_DISABLE, 1);
1888 		break;
1889 	}
1890 
1891 	switch (stream_enc_inst) {
1892 	case 0:
1893 		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,
1894 				SYMCLKA_FE_EN, 1,
1895 				SYMCLKA_FE_SRC_SEL, link_enc_inst);
1896 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1897 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_FE_ROOT_GATE_DISABLE, 1);
1898 		break;
1899 	case 1:
1900 		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,
1901 				SYMCLKB_FE_EN, 1,
1902 				SYMCLKB_FE_SRC_SEL, link_enc_inst);
1903 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1904 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_FE_ROOT_GATE_DISABLE, 1);
1905 		break;
1906 	case 2:
1907 		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,
1908 				SYMCLKC_FE_EN, 1,
1909 				SYMCLKC_FE_SRC_SEL, link_enc_inst);
1910 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1911 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_FE_ROOT_GATE_DISABLE, 1);
1912 		break;
1913 	case 3:
1914 		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,
1915 				SYMCLKD_FE_EN, 1,
1916 				SYMCLKD_FE_SRC_SEL, link_enc_inst);
1917 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1918 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_FE_ROOT_GATE_DISABLE, 1);
1919 		break;
1920 	case 4:
1921 		REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,
1922 				SYMCLKE_FE_EN, 1,
1923 				SYMCLKE_FE_SRC_SEL, link_enc_inst);
1924 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1925 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_FE_ROOT_GATE_DISABLE, 1);
1926 		break;
1927 	}
1928 }
1929 
1930 /*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)1931 static uint8_t dccg35_get_number_enabled_symclk_fe_connected_to_be(struct dccg *dccg, uint32_t link_enc_inst)
1932 {
1933 	uint8_t num_enabled_symclk_fe = 0;
1934 	uint32_t fe_clk_en[5] = {0}, be_clk_sel[5] = {0};
1935 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1936 
1937 	REG_GET_2(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_EN, &fe_clk_en[0],
1938 		SYMCLKA_FE_SRC_SEL, &be_clk_sel[0]);
1939 
1940 	REG_GET_2(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_EN, &fe_clk_en[1],
1941 		SYMCLKB_FE_SRC_SEL, &be_clk_sel[1]);
1942 
1943 	REG_GET_2(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_EN, &fe_clk_en[2],
1944 		SYMCLKC_FE_SRC_SEL, &be_clk_sel[2]);
1945 
1946 	REG_GET_2(SYMCLKD_CLOCK_ENABLE,	SYMCLKD_FE_EN, &fe_clk_en[3],
1947 		SYMCLKD_FE_SRC_SEL, &be_clk_sel[3]);
1948 
1949 	REG_GET_2(SYMCLKE_CLOCK_ENABLE,	SYMCLKE_FE_EN, &fe_clk_en[4],
1950 		SYMCLKE_FE_SRC_SEL, &be_clk_sel[4]);
1951 
1952 	uint8_t i;
1953 
1954 	for (i = 0; i < ARRAY_SIZE(fe_clk_en); i++) {
1955 		if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst)
1956 			num_enabled_symclk_fe++;
1957 	}
1958 	return num_enabled_symclk_fe;
1959 }
1960 
dccg35_disable_symclk_se(struct dccg * dccg,uint32_t stream_enc_inst,uint32_t link_enc_inst)1961 static void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
1962 {
1963 	uint8_t num_enabled_symclk_fe = 0;
1964 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
1965 
1966 	switch (stream_enc_inst) {
1967 	case 0:
1968 		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,
1969 				SYMCLKA_FE_EN, 0,
1970 				SYMCLKA_FE_SRC_SEL, 0);
1971 //		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1972 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_FE_ROOT_GATE_DISABLE, 0);
1973 		break;
1974 	case 1:
1975 		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,
1976 				SYMCLKB_FE_EN, 0,
1977 				SYMCLKB_FE_SRC_SEL, 0);
1978 //		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1979 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_FE_ROOT_GATE_DISABLE, 0);
1980 		break;
1981 	case 2:
1982 		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,
1983 				SYMCLKC_FE_EN, 0,
1984 				SYMCLKC_FE_SRC_SEL, 0);
1985 //		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1986 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_FE_ROOT_GATE_DISABLE, 0);
1987 		break;
1988 	case 3:
1989 		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,
1990 				SYMCLKD_FE_EN, 0,
1991 				SYMCLKD_FE_SRC_SEL, 0);
1992 //		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
1993 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_FE_ROOT_GATE_DISABLE, 0);
1994 		break;
1995 	case 4:
1996 		REG_UPDATE_2(SYMCLKE_CLOCK_ENABLE,
1997 				SYMCLKE_FE_EN, 0,
1998 				SYMCLKE_FE_SRC_SEL, 0);
1999 //		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
2000 //			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_FE_ROOT_GATE_DISABLE, 0);
2001 		break;
2002 	}
2003 
2004 	/*check other enabled symclk fe connected to this be */
2005 	num_enabled_symclk_fe = dccg35_get_number_enabled_symclk_fe_connected_to_be(dccg, link_enc_inst);
2006 	/*only turn off backend clk if other front end attached to this backend are all off,
2007 	 for mst, only turn off the backend if this is the last front end*/
2008 	if (num_enabled_symclk_fe == 0) {
2009 		switch (link_enc_inst) {
2010 		case 0:
2011 			REG_UPDATE(SYMCLKA_CLOCK_ENABLE,
2012 					SYMCLKA_CLOCK_ENABLE, 0);
2013 //			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
2014 //				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_ROOT_GATE_DISABLE, 0);
2015 			break;
2016 		case 1:
2017 			REG_UPDATE(SYMCLKB_CLOCK_ENABLE,
2018 					SYMCLKB_CLOCK_ENABLE, 0);
2019 //			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
2020 //				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_ROOT_GATE_DISABLE, 0);
2021 			break;
2022 		case 2:
2023 			REG_UPDATE(SYMCLKC_CLOCK_ENABLE,
2024 					SYMCLKC_CLOCK_ENABLE, 0);
2025 //			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
2026 //				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_ROOT_GATE_DISABLE, 0);
2027 			break;
2028 		case 3:
2029 			REG_UPDATE(SYMCLKD_CLOCK_ENABLE,
2030 					SYMCLKD_CLOCK_ENABLE, 0);
2031 //			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
2032 //				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_ROOT_GATE_DISABLE, 0);
2033 			break;
2034 		case 4:
2035 			REG_UPDATE(SYMCLKE_CLOCK_ENABLE,
2036 					SYMCLKE_CLOCK_ENABLE, 0);
2037 //			if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
2038 //				REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKE_ROOT_GATE_DISABLE, 0);
2039 			break;
2040 		}
2041 	}
2042 }
2043 
dccg35_set_dpstreamclk_cb(struct dccg * dccg,enum streamclk_source src,int otg_inst,int dp_hpo_inst)2044 static void dccg35_set_dpstreamclk_cb(
2045 		struct dccg *dccg,
2046 		enum streamclk_source src,
2047 		int otg_inst,
2048 		int dp_hpo_inst)
2049 {
2050 
2051 	enum dtbclk_source dtb_clk_src;
2052 	enum dp_stream_clk_source dp_stream_clk_src;
2053 
2054 	switch (src) {
2055 	case REFCLK:
2056 		dtb_clk_src = DTBCLK_REFCLK;
2057 		dp_stream_clk_src = DP_STREAM_REFCLK;
2058 		break;
2059 	case DPREFCLK:
2060 		dtb_clk_src = DTBCLK_DPREFCLK;
2061 		dp_stream_clk_src = (enum dp_stream_clk_source)otg_inst;
2062 		break;
2063 	case DTBCLK0:
2064 		dtb_clk_src = DTBCLK_DTBCLK0;
2065 		dp_stream_clk_src = (enum dp_stream_clk_source)otg_inst;
2066 		break;
2067 	default:
2068 		BREAK_TO_DEBUGGER();
2069 		return;
2070 	}
2071 
2072 	if (dtb_clk_src == DTBCLK_REFCLK &&
2073 		dp_stream_clk_src == DP_STREAM_REFCLK) {
2074 		dccg35_disable_dtbclk_p_new(dccg, otg_inst);
2075 		dccg35_disable_dpstreamclk_new(dccg, dp_hpo_inst);
2076 	} else {
2077 		dccg35_enable_dtbclk_p_new(dccg, dtb_clk_src, otg_inst);
2078 		dccg35_enable_dpstreamclk_new(dccg,
2079 										dp_stream_clk_src,
2080 										dp_hpo_inst);
2081 	}
2082 }
2083 
dccg35_set_dpstreamclk_root_clock_gating_cb(struct dccg * dccg,int dp_hpo_inst,bool power_on)2084 static void dccg35_set_dpstreamclk_root_clock_gating_cb(
2085 	struct dccg *dccg,
2086 	int dp_hpo_inst,
2087 	bool power_on)
2088 {
2089 	/* power_on set indicates we need to ungate
2090 	 * Currently called from optimize_bandwidth and prepare_bandwidth calls
2091 	 * Since clock source is not passed restore to refclock on ungate
2092 	 * Instance 0 is implied here since only one streamclock resource
2093 	 * Redundant as gating when enabled is acheived through set_dpstreamclk
2094 	 */
2095 	if (power_on)
2096 		dccg35_enable_dpstreamclk_new(dccg,
2097 										DP_STREAM_REFCLK,
2098 										dp_hpo_inst);
2099 	else
2100 		dccg35_disable_dpstreamclk_new(dccg, dp_hpo_inst);
2101 }
2102 
dccg35_update_dpp_dto_cb(struct dccg * dccg,int dpp_inst,int req_dppclk)2103 static void dccg35_update_dpp_dto_cb(struct dccg *dccg, int dpp_inst,
2104 				  int req_dppclk)
2105 {
2106 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
2107 
2108 	if (dccg->dpp_clock_gated[dpp_inst]) {
2109 		/*
2110 		 * Do not update the DPPCLK DTO if the clock is stopped.
2111 		 */
2112 		return;
2113 	}
2114 
2115 	if (dccg->ref_dppclk && req_dppclk) {
2116 		int ref_dppclk = dccg->ref_dppclk;
2117 		int modulo, phase;
2118 
2119 		// phase / modulo = dpp pipe clk / dpp global clk
2120 		modulo = 0xff;   // use FF at the end
2121 		phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;
2122 
2123 		if (phase > 0xff) {
2124 			ASSERT(false);
2125 			phase = 0xff;
2126 		}
2127 
2128 		/* Enable DPP CLK DTO output */
2129 		dccg35_enable_dpp_clk_new(dccg, dpp_inst, DPP_DCCG_DTO);
2130 
2131 		/* Program DTO */
2132 		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
2133 				DPPCLK0_DTO_PHASE, phase,
2134 				DPPCLK0_DTO_MODULO, modulo);
2135 	} else
2136 		dccg35_disable_dpp_clk_new(dccg, dpp_inst);
2137 
2138 	dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
2139 }
2140 
dccg35_dpp_root_clock_control_cb(struct dccg * dccg,unsigned int dpp_inst,bool power_on)2141 static void dccg35_dpp_root_clock_control_cb(
2142 	struct dccg *dccg,
2143 	unsigned int dpp_inst,
2144 	bool power_on)
2145 {
2146 	if (dccg->dpp_clock_gated[dpp_inst] == power_on)
2147 		return;
2148 	/* power_on set indicates we need to ungate
2149 	 * Currently called from optimize_bandwidth and prepare_bandwidth calls
2150 	 * Since clock source is not passed restore to refclock on ungate
2151 	 * Redundant as gating when enabled is acheived through update_dpp_dto
2152 	 */
2153 	dccg35_set_dppclk_rcg(dccg, dpp_inst, !power_on);
2154 
2155 	dccg->dpp_clock_gated[dpp_inst] = !power_on;
2156 }
2157 
dccg35_enable_symclk32_se_cb(struct dccg * dccg,int inst,enum phyd32clk_clock_source phyd32clk)2158 static void dccg35_enable_symclk32_se_cb(
2159 	struct dccg *dccg,
2160 	int inst,
2161 	enum phyd32clk_clock_source phyd32clk)
2162 {
2163 	dccg35_enable_symclk32_se_new(dccg, inst, (enum symclk32_se_clk_source)phyd32clk);
2164 }
2165 
dccg35_disable_symclk32_se_cb(struct dccg * dccg,int inst)2166 static void dccg35_disable_symclk32_se_cb(struct dccg *dccg, int inst)
2167 {
2168 	dccg35_disable_symclk32_se_new(dccg, inst);
2169 }
2170 
dccg35_enable_symclk32_le_cb(struct dccg * dccg,int inst,enum phyd32clk_clock_source src)2171 static void dccg35_enable_symclk32_le_cb(
2172 			struct dccg *dccg,
2173 			int inst,
2174 			enum phyd32clk_clock_source src)
2175 {
2176 	dccg35_enable_symclk32_le_new(dccg, inst, (enum symclk32_le_clk_source) src);
2177 }
2178 
dccg35_disable_symclk32_le_cb(struct dccg * dccg,int inst)2179 static void dccg35_disable_symclk32_le_cb(struct dccg *dccg, int inst)
2180 {
2181 	dccg35_disable_symclk32_le_new(dccg, inst);
2182 }
2183 
dccg35_set_symclk32_le_root_clock_gating_cb(struct dccg * dccg,int inst,bool power_on)2184 static void dccg35_set_symclk32_le_root_clock_gating_cb(
2185 	struct dccg *dccg,
2186 	int inst,
2187 	bool power_on)
2188 {
2189 	/* power_on set indicates we need to ungate
2190 	 * Currently called from optimize_bandwidth and prepare_bandwidth calls
2191 	 * Since clock source is not passed restore to refclock on ungate
2192 	 * Redundant as gating when enabled is acheived through disable_symclk32_le
2193 	 */
2194 	if (power_on)
2195 		dccg35_enable_symclk32_le_new(dccg, inst, SYMCLK32_LE_REFCLK);
2196 	else
2197 		dccg35_disable_symclk32_le_new(dccg, inst);
2198 }
2199 
dccg35_set_physymclk_cb(struct dccg * dccg,int inst,enum physymclk_clock_source clk_src,bool force_enable)2200 static void dccg35_set_physymclk_cb(
2201 	struct dccg *dccg,
2202 	int inst,
2203 	enum physymclk_clock_source clk_src,
2204 	bool force_enable)
2205 {
2206 	/* force_enable = 0 indicates we can switch to ref clock */
2207 	if (force_enable)
2208 		dccg35_enable_physymclk_new(dccg, inst, (enum physymclk_source)clk_src);
2209 	else
2210 		dccg35_disable_physymclk_new(dccg, inst);
2211 }
2212 
dccg35_set_physymclk_root_clock_gating_cb(struct dccg * dccg,int inst,bool power_on)2213 static void dccg35_set_physymclk_root_clock_gating_cb(
2214 	struct dccg *dccg,
2215 	int inst,
2216 	bool power_on)
2217 {
2218 	/* Redundant RCG already done in disable_physymclk
2219 	 * power_on = 1 indicates we need to ungate
2220 	 */
2221 	if (power_on)
2222 		dccg35_enable_physymclk_new(dccg, inst, PHYSYMCLK_REFCLK);
2223 	else
2224 		dccg35_disable_physymclk_new(dccg, inst);
2225 }
2226 
dccg35_set_symclk32_le_root_clock_gating(struct dccg * dccg,int inst,bool power_on)2227 static void dccg35_set_symclk32_le_root_clock_gating(
2228 	struct dccg *dccg,
2229 	int inst,
2230 	bool power_on)
2231 {
2232 	/* power_on set indicates we need to ungate
2233 	 * Currently called from optimize_bandwidth and prepare_bandwidth calls
2234 	 * Since clock source is not passed restore to refclock on ungate
2235 	 * Redundant as gating when enabled is acheived through disable_symclk32_le
2236 	 */
2237 	if (power_on)
2238 		dccg35_enable_symclk32_le_new(dccg, inst, SYMCLK32_LE_REFCLK);
2239 	else
2240 		dccg35_disable_symclk32_le_new(dccg, inst);
2241 }
2242 
dccg35_set_dtbclk_p_src_cb(struct dccg * dccg,enum streamclk_source src,uint32_t inst)2243 static void dccg35_set_dtbclk_p_src_cb(
2244 		struct dccg *dccg,
2245 		enum streamclk_source src,
2246 		uint32_t inst)
2247 {
2248 	if (src == DTBCLK0)
2249 		dccg35_enable_dtbclk_p_new(dccg, DTBCLK_DTBCLK0, inst);
2250 	else
2251 		dccg35_disable_dtbclk_p_new(dccg, inst);
2252 }
2253 
dccg35_set_dtbclk_dto_cb(struct dccg * dccg,const struct dtbclk_dto_params * params)2254 static void dccg35_set_dtbclk_dto_cb(
2255 		struct dccg *dccg,
2256 		const struct dtbclk_dto_params *params)
2257 {
2258 	/* set_dtbclk_p_src typ called earlier to switch to DTBCLK
2259 	 * if params->ref_dtbclk_khz and req_dtbclk_khz are 0 switch to ref-clock
2260 	 */
2261 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
2262 	/* DTO Output Rate / Pixel Rate = 1/4 */
2263 	int req_dtbclk_khz = params->pixclk_khz / 4;
2264 
2265 	if (params->ref_dtbclk_khz && req_dtbclk_khz) {
2266 		uint32_t modulo, phase;
2267 
2268 		dccg35_enable_dtbclk_p_new(dccg, DTBCLK_DTBCLK0, params->otg_inst);
2269 
2270 		// phase / modulo = dtbclk / dtbclk ref
2271 		modulo = params->ref_dtbclk_khz * 1000;
2272 		phase = req_dtbclk_khz * 1000;
2273 
2274 		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
2275 		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
2276 
2277 		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
2278 				DTBCLK_DTO_ENABLE[params->otg_inst], 1);
2279 
2280 		REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
2281 				DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
2282 				1, 100);
2283 
2284 		/* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */
2285 		dccg35_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
2286 
2287 		/* The recommended programming sequence to enable DTBCLK DTO to generate
2288 		 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
2289 		 * be set only after DTO is enabled
2290 		 */
2291 		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
2292 				PIPE_DTO_SRC_SEL[params->otg_inst], 2);
2293 	} else {
2294 		dccg35_disable_dtbclk_p_new(dccg, params->otg_inst);
2295 
2296 		REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
2297 					 DTBCLK_DTO_ENABLE[params->otg_inst], 0,
2298 					 PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1);
2299 
2300 		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
2301 		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
2302 	}
2303 }
2304 
dccg35_disable_dscclk_cb(struct dccg * dccg,int inst)2305 static void dccg35_disable_dscclk_cb(struct dccg *dccg,
2306 									 int inst)
2307 {
2308 	dccg35_disable_dscclk_new(dccg, inst);
2309 }
2310 
dccg35_enable_dscclk_cb(struct dccg * dccg,int inst)2311 static void dccg35_enable_dscclk_cb(struct dccg *dccg, int inst)
2312 {
2313 	dccg35_enable_dscclk_new(dccg, inst, DSC_DTO_TUNED_CK_GPU_DISCLK_3);
2314 }
2315 
dccg35_enable_symclk_se_cb(struct dccg * dccg,uint32_t stream_enc_inst,uint32_t link_enc_inst)2316 static void dccg35_enable_symclk_se_cb(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
2317 {
2318 	/* Switch to functional clock if already not selected */
2319 	dccg35_enable_symclk_be_new(dccg, SYMCLK_BE_PHYCLK, link_enc_inst);
2320 
2321 	dccg35_enable_symclk_fe_new(dccg, stream_enc_inst, (enum symclk_fe_source) link_enc_inst);
2322 
2323 }
2324 
dccg35_disable_symclk_se_cb(struct dccg * dccg,uint32_t stream_enc_inst,uint32_t link_enc_inst)2325 static void dccg35_disable_symclk_se_cb(
2326 			struct dccg *dccg,
2327 			uint32_t stream_enc_inst,
2328 			uint32_t link_enc_inst)
2329 {
2330 	dccg35_disable_symclk_fe_new(dccg, stream_enc_inst);
2331 
2332 	/* DMU PHY sequence switches SYMCLK_BE (link_enc_inst) to ref clock once PHY is turned off */
2333 }
2334 
dccg35_root_gate_disable_control(struct dccg * dccg,uint32_t pipe_idx,uint32_t disable_clock_gating)2335 void dccg35_root_gate_disable_control(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating)
2336 {
2337 
2338 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) {
2339 		dccg35_set_dppclk_root_clock_gating(dccg, pipe_idx, disable_clock_gating);
2340 	}
2341 }
2342 
2343 static const struct dccg_funcs dccg35_funcs_new = {
2344 	.update_dpp_dto = dccg35_update_dpp_dto_cb,
2345 	.dpp_root_clock_control = dccg35_dpp_root_clock_control_cb,
2346 	.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
2347 	.dccg_init = dccg35_init_cb,
2348 	.set_dpstreamclk = dccg35_set_dpstreamclk_cb,
2349 	.set_dpstreamclk_root_clock_gating = dccg35_set_dpstreamclk_root_clock_gating_cb,
2350 	.enable_symclk32_se = dccg35_enable_symclk32_se_cb,
2351 	.disable_symclk32_se = dccg35_disable_symclk32_se_cb,
2352 	.enable_symclk32_le = dccg35_enable_symclk32_le_cb,
2353 	.disable_symclk32_le = dccg35_disable_symclk32_le_cb,
2354 	.set_symclk32_le_root_clock_gating = dccg35_set_symclk32_le_root_clock_gating_cb,
2355 	.set_physymclk = dccg35_set_physymclk_cb,
2356 	.set_physymclk_root_clock_gating = dccg35_set_physymclk_root_clock_gating_cb,
2357 	.set_dtbclk_dto = dccg35_set_dtbclk_dto_cb,
2358 	.set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
2359 	.set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
2360 	.otg_add_pixel = dccg31_otg_add_pixel,
2361 	.otg_drop_pixel = dccg31_otg_drop_pixel,
2362 	.set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
2363 	.disable_dsc = dccg35_disable_dscclk_cb,
2364 	.enable_dsc = dccg35_enable_dscclk_cb,
2365 	.set_pixel_rate_div = dccg35_set_pixel_rate_div,
2366 	.get_pixel_rate_div = dccg35_get_pixel_rate_div,
2367 	.trigger_dio_fifo_resync = dccg35_trigger_dio_fifo_resync,
2368 	.set_valid_pixel_rate = dccg35_set_valid_pixel_rate,
2369 	.enable_symclk_se = dccg35_enable_symclk_se_cb,
2370 	.disable_symclk_se = dccg35_disable_symclk_se_cb,
2371 	.set_dtbclk_p_src = dccg35_set_dtbclk_p_src_cb,
2372 };
2373 
2374 static const struct dccg_funcs dccg35_funcs = {
2375 	.update_dpp_dto = dccg35_update_dpp_dto,
2376 	.dpp_root_clock_control = dccg35_dpp_root_clock_control,
2377 	.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
2378 	.dccg_init = dccg35_init,
2379 	.set_dpstreamclk = dccg35_set_dpstreamclk,
2380 	.set_dpstreamclk_root_clock_gating = dccg35_set_dpstreamclk_root_clock_gating,
2381 	.enable_symclk32_se = dccg31_enable_symclk32_se,
2382 	.disable_symclk32_se = dccg35_disable_symclk32_se,
2383 	.enable_symclk32_le = dccg31_enable_symclk32_le,
2384 	.disable_symclk32_le = dccg31_disable_symclk32_le,
2385 	.set_symclk32_le_root_clock_gating = dccg31_set_symclk32_le_root_clock_gating,
2386 	.set_physymclk = dccg35_set_physymclk,
2387 	.set_physymclk_root_clock_gating = dccg35_set_physymclk_root_clock_gating,
2388 	.set_dtbclk_dto = dccg35_set_dtbclk_dto,
2389 	.set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
2390 	.set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
2391 	.otg_add_pixel = dccg31_otg_add_pixel,
2392 	.otg_drop_pixel = dccg31_otg_drop_pixel,
2393 	.set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
2394 	.disable_dsc = dccg35_disable_dscclk,
2395 	.enable_dsc = dccg35_enable_dscclk,
2396 	.set_pixel_rate_div = dccg35_set_pixel_rate_div,
2397 	.get_pixel_rate_div = dccg35_get_pixel_rate_div,
2398 	.trigger_dio_fifo_resync = dccg35_trigger_dio_fifo_resync,
2399 	.set_valid_pixel_rate = dccg35_set_valid_pixel_rate,
2400 	.enable_symclk_se = dccg35_enable_symclk_se,
2401 	.disable_symclk_se = dccg35_disable_symclk_se,
2402 	.set_dtbclk_p_src = dccg35_set_dtbclk_p_src,
2403 	.dccg_root_gate_disable_control = dccg35_root_gate_disable_control,
2404 };
2405 
dccg35_create(struct dc_context * ctx,const struct dccg_registers * regs,const struct dccg_shift * dccg_shift,const struct dccg_mask * dccg_mask)2406 struct dccg *dccg35_create(
2407 	struct dc_context *ctx,
2408 	const struct dccg_registers *regs,
2409 	const struct dccg_shift *dccg_shift,
2410 	const struct dccg_mask *dccg_mask)
2411 {
2412 	struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
2413 	struct dccg *base;
2414 
2415 	if (dccg_dcn == NULL) {
2416 		BREAK_TO_DEBUGGER();
2417 		return NULL;
2418 	}
2419 	(void)&dccg35_disable_symclk_be_new;
2420 	(void)&dccg35_set_symclk32_le_root_clock_gating;
2421 	(void)&dccg35_set_smclk32_se_rcg;
2422 	(void)&dccg35_funcs_new;
2423 
2424 	base = &dccg_dcn->base;
2425 	base->ctx = ctx;
2426 	base->funcs = &dccg35_funcs;
2427 
2428 	dccg_dcn->regs = regs;
2429 	dccg_dcn->dccg_shift = dccg_shift;
2430 	dccg_dcn->dccg_mask = dccg_mask;
2431 
2432 	return &dccg_dcn->base;
2433 }
2434