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