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