1 /*
2  * Copyright 2018 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 #include "reg_helper.h"
27 #include "core_types.h"
28 #include "dcn31_dccg.h"
29 #include "dal_asic_id.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 #define DC_LOGGER \
44 	dccg->ctx->logger
45 
46 static void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
47 {
48 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
49 
50 	if (dccg->ref_dppclk && req_dppclk) {
51 		int ref_dppclk = dccg->ref_dppclk;
52 		int modulo, phase;
53 
54 		// phase / modulo = dpp pipe clk / dpp global clk
55 		modulo = 0xff;   // use FF at the end
56 		phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;
57 
58 		if (phase > 0xff) {
59 			ASSERT(false);
60 			phase = 0xff;
61 		}
62 
63 		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
64 				DPPCLK0_DTO_PHASE, phase,
65 				DPPCLK0_DTO_MODULO, modulo);
66 		REG_UPDATE(DPPCLK_DTO_CTRL,
67 				DPPCLK_DTO_ENABLE[dpp_inst], 1);
68 	} else {
69 		//DTO must be enabled to generate a 0Hz clock output
70 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) {
71 			REG_UPDATE(DPPCLK_DTO_CTRL,
72 					DPPCLK_DTO_ENABLE[dpp_inst], 1);
73 			REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
74 					DPPCLK0_DTO_PHASE, 0,
75 					DPPCLK0_DTO_MODULO, 1);
76 		} else {
77 			REG_UPDATE(DPPCLK_DTO_CTRL,
78 					DPPCLK_DTO_ENABLE[dpp_inst], 0);
79 		}
80 	}
81 	dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
82 }
83 
84 static enum phyd32clk_clock_source get_phy_mux_symclk(
85 		struct dcn_dccg *dccg_dcn,
86 		enum phyd32clk_clock_source src)
87 {
88 	if (dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
89 		if (src == PHYD32CLKC)
90 			src = PHYD32CLKF;
91 		if (src == PHYD32CLKD)
92 			src = PHYD32CLKG;
93 	}
94 	return src;
95 }
96 
97 static void dccg31_enable_dpstreamclk(struct dccg *dccg, int otg_inst)
98 {
99 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
100 
101 	/* enabled to select one of the DTBCLKs for pipe */
102 	switch (otg_inst) {
103 	case 0:
104 		REG_UPDATE(DPSTREAMCLK_CNTL,
105 				DPSTREAMCLK_PIPE0_EN, 1);
106 		break;
107 	case 1:
108 		REG_UPDATE(DPSTREAMCLK_CNTL,
109 				DPSTREAMCLK_PIPE1_EN, 1);
110 		break;
111 	case 2:
112 		REG_UPDATE(DPSTREAMCLK_CNTL,
113 				DPSTREAMCLK_PIPE2_EN, 1);
114 		break;
115 	case 3:
116 		REG_UPDATE(DPSTREAMCLK_CNTL,
117 				DPSTREAMCLK_PIPE3_EN, 1);
118 		break;
119 	default:
120 		BREAK_TO_DEBUGGER();
121 		return;
122 	}
123 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
124 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
125 			DPSTREAMCLK_GATE_DISABLE, 1,
126 			DPSTREAMCLK_ROOT_GATE_DISABLE, 1);
127 }
128 
129 static void dccg31_disable_dpstreamclk(struct dccg *dccg, int otg_inst)
130 {
131 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
132 
133 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
134 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
135 				DPSTREAMCLK_ROOT_GATE_DISABLE, 0,
136 				DPSTREAMCLK_GATE_DISABLE, 0);
137 
138 	switch (otg_inst) {
139 	case 0:
140 		REG_UPDATE(DPSTREAMCLK_CNTL,
141 				DPSTREAMCLK_PIPE0_EN, 0);
142 		break;
143 	case 1:
144 		REG_UPDATE(DPSTREAMCLK_CNTL,
145 				DPSTREAMCLK_PIPE1_EN, 0);
146 		break;
147 	case 2:
148 		REG_UPDATE(DPSTREAMCLK_CNTL,
149 				DPSTREAMCLK_PIPE2_EN, 0);
150 		break;
151 	case 3:
152 		REG_UPDATE(DPSTREAMCLK_CNTL,
153 				DPSTREAMCLK_PIPE3_EN, 0);
154 		break;
155 	default:
156 		BREAK_TO_DEBUGGER();
157 		return;
158 	}
159 }
160 
161 void dccg31_set_dpstreamclk(
162 		struct dccg *dccg,
163 		enum hdmistreamclk_source src,
164 		int otg_inst)
165 {
166 	if (src == REFCLK)
167 		dccg31_disable_dpstreamclk(dccg, otg_inst);
168 	else
169 		dccg31_enable_dpstreamclk(dccg, otg_inst);
170 }
171 
172 void dccg31_enable_symclk32_se(
173 		struct dccg *dccg,
174 		int hpo_se_inst,
175 		enum phyd32clk_clock_source phyd32clk)
176 {
177 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
178 
179 	phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk);
180 
181 	/* select one of the PHYD32CLKs as the source for symclk32_se */
182 	switch (hpo_se_inst) {
183 	case 0:
184 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
185 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
186 					SYMCLK32_SE0_GATE_DISABLE, 1,
187 					SYMCLK32_ROOT_SE0_GATE_DISABLE, 1);
188 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
189 				SYMCLK32_SE0_SRC_SEL, phyd32clk,
190 				SYMCLK32_SE0_EN, 1);
191 		break;
192 	case 1:
193 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
194 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
195 					SYMCLK32_SE1_GATE_DISABLE, 1,
196 					SYMCLK32_ROOT_SE1_GATE_DISABLE, 1);
197 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
198 				SYMCLK32_SE1_SRC_SEL, phyd32clk,
199 				SYMCLK32_SE1_EN, 1);
200 		break;
201 	case 2:
202 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
203 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
204 					SYMCLK32_SE2_GATE_DISABLE, 1,
205 					SYMCLK32_ROOT_SE2_GATE_DISABLE, 1);
206 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
207 				SYMCLK32_SE2_SRC_SEL, phyd32clk,
208 				SYMCLK32_SE2_EN, 1);
209 		break;
210 	case 3:
211 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
212 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
213 					SYMCLK32_SE3_GATE_DISABLE, 1,
214 					SYMCLK32_ROOT_SE3_GATE_DISABLE, 1);
215 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
216 				SYMCLK32_SE3_SRC_SEL, phyd32clk,
217 				SYMCLK32_SE3_EN, 1);
218 		break;
219 	default:
220 		BREAK_TO_DEBUGGER();
221 		return;
222 	}
223 }
224 
225 void dccg31_disable_symclk32_se(
226 		struct dccg *dccg,
227 		int hpo_se_inst)
228 {
229 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
230 
231 	/* set refclk as the source for symclk32_se */
232 	switch (hpo_se_inst) {
233 	case 0:
234 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
235 				SYMCLK32_SE0_SRC_SEL, 0,
236 				SYMCLK32_SE0_EN, 0);
237 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
238 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
239 					SYMCLK32_SE0_GATE_DISABLE, 0,
240 					SYMCLK32_ROOT_SE0_GATE_DISABLE, 0);
241 		break;
242 	case 1:
243 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
244 				SYMCLK32_SE1_SRC_SEL, 0,
245 				SYMCLK32_SE1_EN, 0);
246 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
247 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
248 					SYMCLK32_SE1_GATE_DISABLE, 0,
249 					SYMCLK32_ROOT_SE1_GATE_DISABLE, 0);
250 		break;
251 	case 2:
252 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
253 				SYMCLK32_SE2_SRC_SEL, 0,
254 				SYMCLK32_SE2_EN, 0);
255 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
256 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
257 					SYMCLK32_SE2_GATE_DISABLE, 0,
258 					SYMCLK32_ROOT_SE2_GATE_DISABLE, 0);
259 		break;
260 	case 3:
261 		REG_UPDATE_2(SYMCLK32_SE_CNTL,
262 				SYMCLK32_SE3_SRC_SEL, 0,
263 				SYMCLK32_SE3_EN, 0);
264 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
265 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
266 					SYMCLK32_SE3_GATE_DISABLE, 0,
267 					SYMCLK32_ROOT_SE3_GATE_DISABLE, 0);
268 		break;
269 	default:
270 		BREAK_TO_DEBUGGER();
271 		return;
272 	}
273 }
274 
275 void dccg31_enable_symclk32_le(
276 		struct dccg *dccg,
277 		int hpo_le_inst,
278 		enum phyd32clk_clock_source phyd32clk)
279 {
280 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
281 
282 	phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk);
283 
284 	/* select one of the PHYD32CLKs as the source for symclk32_le */
285 	switch (hpo_le_inst) {
286 	case 0:
287 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
288 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
289 					SYMCLK32_LE0_GATE_DISABLE, 1,
290 					SYMCLK32_ROOT_LE0_GATE_DISABLE, 1);
291 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
292 				SYMCLK32_LE0_SRC_SEL, phyd32clk,
293 				SYMCLK32_LE0_EN, 1);
294 		break;
295 	case 1:
296 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
297 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
298 					SYMCLK32_LE1_GATE_DISABLE, 1,
299 					SYMCLK32_ROOT_LE1_GATE_DISABLE, 1);
300 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
301 				SYMCLK32_LE1_SRC_SEL, phyd32clk,
302 				SYMCLK32_LE1_EN, 1);
303 		break;
304 	default:
305 		BREAK_TO_DEBUGGER();
306 		return;
307 	}
308 }
309 
310 void dccg31_disable_symclk32_le(
311 		struct dccg *dccg,
312 		int hpo_le_inst)
313 {
314 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
315 
316 	/* set refclk as the source for symclk32_le */
317 	switch (hpo_le_inst) {
318 	case 0:
319 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
320 				SYMCLK32_LE0_SRC_SEL, 0,
321 				SYMCLK32_LE0_EN, 0);
322 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
323 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
324 					SYMCLK32_LE0_GATE_DISABLE, 0,
325 					SYMCLK32_ROOT_LE0_GATE_DISABLE, 0);
326 		break;
327 	case 1:
328 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
329 				SYMCLK32_LE1_SRC_SEL, 0,
330 				SYMCLK32_LE1_EN, 0);
331 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
332 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
333 					SYMCLK32_LE1_GATE_DISABLE, 0,
334 					SYMCLK32_ROOT_LE1_GATE_DISABLE, 0);
335 		break;
336 	default:
337 		BREAK_TO_DEBUGGER();
338 		return;
339 	}
340 }
341 
342 static void dccg31_disable_dscclk(struct dccg *dccg, int inst)
343 {
344 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
345 
346 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
347 		return;
348 	//DTO must be enabled to generate a 0 Hz clock output
349 	switch (inst) {
350 	case 0:
351 		REG_UPDATE(DSCCLK_DTO_CTRL,
352 				DSCCLK0_DTO_ENABLE, 1);
353 		REG_UPDATE_2(DSCCLK0_DTO_PARAM,
354 				DSCCLK0_DTO_PHASE, 0,
355 				DSCCLK0_DTO_MODULO, 1);
356 		break;
357 	case 1:
358 		REG_UPDATE(DSCCLK_DTO_CTRL,
359 				DSCCLK1_DTO_ENABLE, 1);
360 		REG_UPDATE_2(DSCCLK1_DTO_PARAM,
361 				DSCCLK1_DTO_PHASE, 0,
362 				DSCCLK1_DTO_MODULO, 1);
363 		break;
364 	case 2:
365 		REG_UPDATE(DSCCLK_DTO_CTRL,
366 				DSCCLK2_DTO_ENABLE, 1);
367 		REG_UPDATE_2(DSCCLK2_DTO_PARAM,
368 				DSCCLK2_DTO_PHASE, 0,
369 				DSCCLK2_DTO_MODULO, 1);
370 		break;
371 	default:
372 		BREAK_TO_DEBUGGER();
373 		return;
374 	}
375 }
376 
377 static void dccg31_enable_dscclk(struct dccg *dccg, int inst)
378 {
379 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
380 
381 	if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
382 		return;
383 	//Disable DTO
384 	switch (inst) {
385 	case 0:
386 		REG_UPDATE_2(DSCCLK0_DTO_PARAM,
387 				DSCCLK0_DTO_PHASE, 0,
388 				DSCCLK0_DTO_MODULO, 0);
389 		REG_UPDATE(DSCCLK_DTO_CTRL,
390 				DSCCLK0_DTO_ENABLE, 0);
391 		break;
392 	case 1:
393 		REG_UPDATE_2(DSCCLK1_DTO_PARAM,
394 				DSCCLK1_DTO_PHASE, 0,
395 				DSCCLK1_DTO_MODULO, 0);
396 		REG_UPDATE(DSCCLK_DTO_CTRL,
397 				DSCCLK1_DTO_ENABLE, 0);
398 		break;
399 	case 2:
400 		REG_UPDATE_2(DSCCLK2_DTO_PARAM,
401 				DSCCLK2_DTO_PHASE, 0,
402 				DSCCLK2_DTO_MODULO, 0);
403 		REG_UPDATE(DSCCLK_DTO_CTRL,
404 				DSCCLK2_DTO_ENABLE, 0);
405 		break;
406 	default:
407 		BREAK_TO_DEBUGGER();
408 		return;
409 	}
410 }
411 
412 void dccg31_set_physymclk(
413 		struct dccg *dccg,
414 		int phy_inst,
415 		enum physymclk_clock_source clk_src,
416 		bool force_enable)
417 {
418 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
419 
420 	/* Force PHYSYMCLK on and Select phyd32clk as the source of clock which is output to PHY through DCIO */
421 	switch (phy_inst) {
422 	case 0:
423 		if (force_enable) {
424 			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
425 					PHYASYMCLK_FORCE_EN, 1,
426 					PHYASYMCLK_FORCE_SRC_SEL, clk_src);
427 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
428 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
429 					PHYASYMCLK_GATE_DISABLE, 1);
430 		} else {
431 			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
432 					PHYASYMCLK_FORCE_EN, 0,
433 					PHYASYMCLK_FORCE_SRC_SEL, 0);
434 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
435 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
436 					PHYASYMCLK_GATE_DISABLE, 0);
437 		}
438 		break;
439 	case 1:
440 		if (force_enable) {
441 			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
442 					PHYBSYMCLK_FORCE_EN, 1,
443 					PHYBSYMCLK_FORCE_SRC_SEL, clk_src);
444 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
445 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
446 					PHYBSYMCLK_GATE_DISABLE, 1);
447 		} else {
448 			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
449 					PHYBSYMCLK_FORCE_EN, 0,
450 					PHYBSYMCLK_FORCE_SRC_SEL, 0);
451 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
452 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
453 					PHYBSYMCLK_GATE_DISABLE, 0);
454 		}
455 		break;
456 	case 2:
457 		if (force_enable) {
458 			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
459 					PHYCSYMCLK_FORCE_EN, 1,
460 					PHYCSYMCLK_FORCE_SRC_SEL, clk_src);
461 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
462 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
463 					PHYCSYMCLK_GATE_DISABLE, 1);
464 		} else {
465 			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
466 					PHYCSYMCLK_FORCE_EN, 0,
467 					PHYCSYMCLK_FORCE_SRC_SEL, 0);
468 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
469 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
470 					PHYCSYMCLK_GATE_DISABLE, 0);
471 		}
472 		break;
473 	case 3:
474 		if (force_enable) {
475 			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
476 					PHYDSYMCLK_FORCE_EN, 1,
477 					PHYDSYMCLK_FORCE_SRC_SEL, clk_src);
478 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
479 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
480 					PHYDSYMCLK_GATE_DISABLE, 1);
481 		} else {
482 			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
483 					PHYDSYMCLK_FORCE_EN, 0,
484 					PHYDSYMCLK_FORCE_SRC_SEL, 0);
485 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
486 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
487 					PHYDSYMCLK_GATE_DISABLE, 0);
488 		}
489 		break;
490 	case 4:
491 		if (force_enable) {
492 			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
493 					PHYESYMCLK_FORCE_EN, 1,
494 					PHYESYMCLK_FORCE_SRC_SEL, clk_src);
495 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
496 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
497 					PHYESYMCLK_GATE_DISABLE, 1);
498 		} else {
499 			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
500 					PHYESYMCLK_FORCE_EN, 0,
501 					PHYESYMCLK_FORCE_SRC_SEL, 0);
502 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
503 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
504 					PHYESYMCLK_GATE_DISABLE, 0);
505 		}
506 		break;
507 	default:
508 		BREAK_TO_DEBUGGER();
509 		return;
510 	}
511 }
512 
513 /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
514 static void dccg31_set_dtbclk_dto(
515 		struct dccg *dccg,
516 		int dtbclk_inst,
517 		int req_dtbclk_khz,
518 		int num_odm_segments,
519 		const struct dc_crtc_timing *timing)
520 {
521 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
522 	uint32_t dtbdto_div;
523 
524 	/* Mode	                DTBDTO Rate       DTBCLK_DTO<x>_DIV Register
525 	 * ODM 4:1 combine      pixel rate/4      2
526 	 * ODM 2:1 combine      pixel rate/2      4
527 	 * non-DSC 4:2:0 mode   pixel rate/2      4
528 	 * DSC native 4:2:0     pixel rate/2      4
529 	 * DSC native 4:2:2     pixel rate/2      4
530 	 * Other modes          pixel rate        8
531 	 */
532 	if (num_odm_segments == 4) {
533 		dtbdto_div = 2;
534 		req_dtbclk_khz = req_dtbclk_khz / 4;
535 	} else if ((num_odm_segments == 2) ||
536 			(timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ||
537 			(timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
538 					&& !timing->dsc_cfg.ycbcr422_simple)) {
539 		dtbdto_div = 4;
540 		req_dtbclk_khz = req_dtbclk_khz / 2;
541 	} else
542 		dtbdto_div = 8;
543 
544 	if (dccg->ref_dtbclk_khz && req_dtbclk_khz) {
545 		uint32_t modulo, phase;
546 
547 		// phase / modulo = dtbclk / dtbclk ref
548 		modulo = dccg->ref_dtbclk_khz * 1000;
549 		phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + dccg->ref_dtbclk_khz - 1),
550 			dccg->ref_dtbclk_khz);
551 
552 		REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
553 				DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div);
554 
555 		REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], modulo);
556 		REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], phase);
557 
558 		REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
559 				DTBCLK_DTO_ENABLE[dtbclk_inst], 1);
560 
561 		REG_WAIT(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
562 				DTBCLKDTO_ENABLE_STATUS[dtbclk_inst], 1,
563 				1, 100);
564 
565 		/* The recommended programming sequence to enable DTBCLK DTO to generate
566 		 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
567 		 * be set only after DTO is enabled
568 		 */
569 		REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
570 				PIPE_DTO_SRC_SEL[dtbclk_inst], 1);
571 
572 		dccg->dtbclk_khz[dtbclk_inst] = req_dtbclk_khz;
573 	} else {
574 		REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
575 				DTBCLK_DTO_ENABLE[dtbclk_inst], 0,
576 				PIPE_DTO_SRC_SEL[dtbclk_inst], 0,
577 				DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div);
578 
579 		REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], 0);
580 		REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], 0);
581 
582 		dccg->dtbclk_khz[dtbclk_inst] = 0;
583 	}
584 }
585 
586 void dccg31_set_audio_dtbclk_dto(
587 		struct dccg *dccg,
588 		uint32_t req_audio_dtbclk_khz)
589 {
590 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
591 
592 	if (dccg->ref_dtbclk_khz && req_audio_dtbclk_khz) {
593 		uint32_t modulo, phase;
594 
595 		// phase / modulo = dtbclk / dtbclk ref
596 		modulo = dccg->ref_dtbclk_khz * 1000;
597 		phase = div_u64((((unsigned long long)modulo * req_audio_dtbclk_khz) + dccg->ref_dtbclk_khz - 1),
598 			dccg->ref_dtbclk_khz);
599 
600 
601 		REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, modulo);
602 		REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, phase);
603 
604 		//REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
605 		//		DCCG_AUDIO_DTBCLK_DTO_USE_512FBR_DTO, 1);
606 
607 		REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
608 				DCCG_AUDIO_DTO_SEL, 4);  //  04 - DCCG_AUDIO_DTO_SEL_AUDIO_DTO_DTBCLK
609 
610 		dccg->audio_dtbclk_khz = req_audio_dtbclk_khz;
611 	} else {
612 		REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, 0);
613 		REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, 0);
614 
615 		REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
616 				DCCG_AUDIO_DTO_SEL, 3);  //  03 - DCCG_AUDIO_DTO_SEL_NO_AUDIO_DTO
617 
618 		dccg->audio_dtbclk_khz = 0;
619 	}
620 }
621 
622 static void dccg31_get_dccg_ref_freq(struct dccg *dccg,
623 		unsigned int xtalin_freq_inKhz,
624 		unsigned int *dccg_ref_freq_inKhz)
625 {
626 	/*
627 	 * Assume refclk is sourced from xtalin
628 	 * expect 24MHz
629 	 */
630 	*dccg_ref_freq_inKhz = xtalin_freq_inKhz;
631 	return;
632 }
633 
634 static void dccg31_set_dispclk_change_mode(
635 	struct dccg *dccg,
636 	enum dentist_dispclk_change_mode change_mode)
637 {
638 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
639 
640 	REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE,
641 		   change_mode == DISPCLK_CHANGE_MODE_RAMPING ? 2 : 0);
642 }
643 
644 void dccg31_init(struct dccg *dccg)
645 {
646 	/* Set HPO stream encoder to use refclk to avoid case where PHY is
647 	 * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which
648 	 * will cause DCN to hang.
649 	 */
650 	dccg31_disable_symclk32_se(dccg, 0);
651 	dccg31_disable_symclk32_se(dccg, 1);
652 	dccg31_disable_symclk32_se(dccg, 2);
653 	dccg31_disable_symclk32_se(dccg, 3);
654 
655 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) {
656 		dccg31_disable_symclk32_le(dccg, 0);
657 		dccg31_disable_symclk32_le(dccg, 1);
658 	}
659 
660 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
661 		dccg31_disable_dpstreamclk(dccg, 0);
662 		dccg31_disable_dpstreamclk(dccg, 1);
663 		dccg31_disable_dpstreamclk(dccg, 2);
664 		dccg31_disable_dpstreamclk(dccg, 3);
665 	}
666 
667 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) {
668 		dccg31_set_physymclk(dccg, 0, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
669 		dccg31_set_physymclk(dccg, 1, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
670 		dccg31_set_physymclk(dccg, 2, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
671 		dccg31_set_physymclk(dccg, 3, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
672 		dccg31_set_physymclk(dccg, 4, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
673 	}
674 }
675 
676 static const struct dccg_funcs dccg31_funcs = {
677 	.update_dpp_dto = dccg31_update_dpp_dto,
678 	.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
679 	.dccg_init = dccg31_init,
680 	.set_dpstreamclk = dccg31_set_dpstreamclk,
681 	.enable_symclk32_se = dccg31_enable_symclk32_se,
682 	.disable_symclk32_se = dccg31_disable_symclk32_se,
683 	.enable_symclk32_le = dccg31_enable_symclk32_le,
684 	.disable_symclk32_le = dccg31_disable_symclk32_le,
685 	.set_physymclk = dccg31_set_physymclk,
686 	.set_dtbclk_dto = dccg31_set_dtbclk_dto,
687 	.set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
688 	.set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
689 	.disable_dsc = dccg31_disable_dscclk,
690 	.enable_dsc = dccg31_enable_dscclk,
691 };
692 
693 struct dccg *dccg31_create(
694 	struct dc_context *ctx,
695 	const struct dccg_registers *regs,
696 	const struct dccg_shift *dccg_shift,
697 	const struct dccg_mask *dccg_mask)
698 {
699 	struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
700 	struct dccg *base;
701 
702 	if (dccg_dcn == NULL) {
703 		BREAK_TO_DEBUGGER();
704 		return NULL;
705 	}
706 
707 	base = &dccg_dcn->base;
708 	base->ctx = ctx;
709 	base->funcs = &dccg31_funcs;
710 
711 	dccg_dcn->regs = regs;
712 	dccg_dcn->dccg_shift = dccg_shift;
713 	dccg_dcn->dccg_mask = dccg_mask;
714 
715 	return &dccg_dcn->base;
716 }
717