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