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