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