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