1 /*
2  * Copyright 2023 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 "dcn401_dccg.h"
29 #include "dcn31/dcn31_dccg.h"
30 
31 /*
32 #include "dmub_common.h"
33 #include "dmcub_reg_access_helper.h"
34 
35 #include "dmub401_common.h"
36 #include "dmub401_regs.h"
37 #include "dmub401_dccg.h"
38 */
39 
40 #define TO_DCN_DCCG(dccg)\
41 	container_of(dccg, struct dcn_dccg, base)
42 
43 #define REG(reg) \
44 	(dccg_dcn->regs->reg)
45 
46 #undef FN
47 #define FN(reg_name, field_name) \
48 	dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name
49 
50 #define CTX \
51 	dccg_dcn->base.ctx
52 #define DC_LOGGER \
53 	dccg->ctx->logger
54 
dcn401_set_dppclk_enable(struct dccg * dccg,uint32_t dpp_inst,uint32_t enable)55 static void dcn401_set_dppclk_enable(struct dccg *dccg,
56 				 uint32_t dpp_inst, uint32_t enable)
57 {
58 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
59 
60 	switch (dpp_inst) {
61 	case 0:
62 		REG_UPDATE(DPPCLK_CTRL, DPPCLK0_EN, enable);
63 		break;
64 	case 1:
65 		REG_UPDATE(DPPCLK_CTRL, DPPCLK1_EN, enable);
66 		break;
67 	case 2:
68 		REG_UPDATE(DPPCLK_CTRL, DPPCLK2_EN, enable);
69 		break;
70 	case 3:
71 		REG_UPDATE(DPPCLK_CTRL, DPPCLK3_EN, enable);
72 		break;
73 	default:
74 		break;
75 	}
76 }
dccg401_update_dpp_dto(struct dccg * dccg,int dpp_inst,int req_dppclk)77 void dccg401_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
78 {
79 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
80 
81 	if (dccg->ref_dppclk && req_dppclk) {
82 		int ref_dppclk = dccg->ref_dppclk;
83 		int modulo, phase;
84 
85 		// phase / modulo = dpp pipe clk / dpp global clk
86 		modulo = 0xff;   // use FF at the end
87 		phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk;
88 
89 		if (phase > 0xff) {
90 			ASSERT(false);
91 			phase = 0xff;
92 		}
93 
94 		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
95 				DPPCLK0_DTO_PHASE, phase,
96 				DPPCLK0_DTO_MODULO, modulo);
97 		dcn401_set_dppclk_enable(dccg, dpp_inst, true);
98 	} else {
99 		dcn401_set_dppclk_enable(dccg, dpp_inst, false);
100 	}
101 
102 	dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
103 }
104 
105 /* This function is a workaround for writing to OTG_PIXEL_RATE_DIV
106  * without the probability of causing a DIG FIFO error.
107  */
dccg401_wait_for_dentist_change_done(struct dccg * dccg)108 static void dccg401_wait_for_dentist_change_done(
109 	struct dccg *dccg)
110 {
111 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
112 
113 	uint32_t dentist_dispclk_value = REG_READ(DENTIST_DISPCLK_CNTL);
114 
115 	REG_WRITE(DENTIST_DISPCLK_CNTL, dentist_dispclk_value);
116 	REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000);
117 }
118 
dccg401_get_pixel_rate_div(struct dccg * dccg,uint32_t otg_inst,uint32_t * tmds_div,uint32_t * dp_dto_int)119 static void dccg401_get_pixel_rate_div(
120 		struct dccg *dccg,
121 		uint32_t otg_inst,
122 		uint32_t *tmds_div,
123 		uint32_t *dp_dto_int)
124 {
125 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
126 	uint32_t val_tmds_div = PIXEL_RATE_DIV_NA;
127 
128 	switch (otg_inst) {
129 	case 0:
130 		REG_GET_2(OTG_PIXEL_RATE_DIV,
131 			OTG0_TMDS_PIXEL_RATE_DIV, &val_tmds_div,
132 			DPDTO0_INT, dp_dto_int);
133 		break;
134 	case 1:
135 		REG_GET_2(OTG_PIXEL_RATE_DIV,
136 			OTG1_TMDS_PIXEL_RATE_DIV, &val_tmds_div,
137 			DPDTO1_INT, dp_dto_int);
138 		break;
139 	case 2:
140 		REG_GET_2(OTG_PIXEL_RATE_DIV,
141 			OTG2_TMDS_PIXEL_RATE_DIV, &val_tmds_div,
142 			DPDTO2_INT, dp_dto_int);
143 		break;
144 	case 3:
145 		REG_GET_2(OTG_PIXEL_RATE_DIV,
146 			OTG3_TMDS_PIXEL_RATE_DIV, &val_tmds_div,
147 			DPDTO3_INT, dp_dto_int);
148 		break;
149 	default:
150 		BREAK_TO_DEBUGGER();
151 		return;
152 	}
153 
154 	*tmds_div = val_tmds_div == 0 ? PIXEL_RATE_DIV_BY_2 : PIXEL_RATE_DIV_BY_4;
155 }
156 
dccg401_set_pixel_rate_div(struct dccg * dccg,uint32_t otg_inst,enum pixel_rate_div tmds_div,enum pixel_rate_div unused)157 static void dccg401_set_pixel_rate_div(
158 		struct dccg *dccg,
159 		uint32_t otg_inst,
160 		enum pixel_rate_div tmds_div,
161 		enum pixel_rate_div unused)
162 {
163 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
164 	uint32_t cur_tmds_div = PIXEL_RATE_DIV_NA;
165 	uint32_t dp_dto_int;
166 	uint32_t reg_val;
167 
168 	// only 2 and 4 are valid on dcn401
169 	if (tmds_div != PIXEL_RATE_DIV_BY_2 && tmds_div != PIXEL_RATE_DIV_BY_4) {
170 		return;
171 	}
172 
173 	dccg401_get_pixel_rate_div(dccg, otg_inst, &cur_tmds_div, &dp_dto_int);
174 	if (tmds_div == cur_tmds_div)
175 		return;
176 
177 	// encode enum to register value
178 	reg_val = tmds_div == PIXEL_RATE_DIV_BY_4 ? 1 : 0;
179 
180 	switch (otg_inst) {
181 	case 0:
182 		REG_UPDATE(OTG_PIXEL_RATE_DIV,
183 				OTG0_TMDS_PIXEL_RATE_DIV, reg_val);
184 
185 		dccg401_wait_for_dentist_change_done(dccg);
186 		break;
187 	case 1:
188 		REG_UPDATE(OTG_PIXEL_RATE_DIV,
189 				OTG1_TMDS_PIXEL_RATE_DIV, reg_val);
190 
191 		dccg401_wait_for_dentist_change_done(dccg);
192 		break;
193 	case 2:
194 		REG_UPDATE(OTG_PIXEL_RATE_DIV,
195 				OTG2_TMDS_PIXEL_RATE_DIV, reg_val);
196 
197 		dccg401_wait_for_dentist_change_done(dccg);
198 		break;
199 	case 3:
200 		REG_UPDATE(OTG_PIXEL_RATE_DIV,
201 				OTG3_TMDS_PIXEL_RATE_DIV, reg_val);
202 
203 		dccg401_wait_for_dentist_change_done(dccg);
204 		break;
205 	default:
206 		BREAK_TO_DEBUGGER();
207 		return;
208 	}
209 }
210 
211 
dccg401_set_dtbclk_p_src(struct dccg * dccg,enum streamclk_source src,uint32_t otg_inst)212 static void dccg401_set_dtbclk_p_src(
213 		struct dccg *dccg,
214 		enum streamclk_source src,
215 		uint32_t otg_inst)
216 {
217 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
218 
219 	uint32_t p_src_sel = 0; /* selects dprefclk */
220 	if (src == DTBCLK0)
221 		p_src_sel = 2;  /* selects dtbclk0 */
222 
223 	switch (otg_inst) {
224 	case 0:
225 		if (src == REFCLK)
226 			REG_UPDATE(DTBCLK_P_CNTL,
227 					DTBCLK_P0_EN, 0);
228 		else
229 			REG_UPDATE_2(DTBCLK_P_CNTL,
230 					DTBCLK_P0_SRC_SEL, p_src_sel,
231 					DTBCLK_P0_EN, 1);
232 		break;
233 	case 1:
234 		if (src == REFCLK)
235 			REG_UPDATE(DTBCLK_P_CNTL,
236 					DTBCLK_P1_EN, 0);
237 		else
238 			REG_UPDATE_2(DTBCLK_P_CNTL,
239 					DTBCLK_P1_SRC_SEL, p_src_sel,
240 					DTBCLK_P1_EN, 1);
241 		break;
242 	case 2:
243 		if (src == REFCLK)
244 			REG_UPDATE(DTBCLK_P_CNTL,
245 					DTBCLK_P2_EN, 0);
246 		else
247 			REG_UPDATE_2(DTBCLK_P_CNTL,
248 					DTBCLK_P2_SRC_SEL, p_src_sel,
249 					DTBCLK_P2_EN, 1);
250 		break;
251 	case 3:
252 		if (src == REFCLK)
253 			REG_UPDATE(DTBCLK_P_CNTL,
254 					DTBCLK_P3_EN, 0);
255 		else
256 			REG_UPDATE_2(DTBCLK_P_CNTL,
257 					DTBCLK_P3_SRC_SEL, p_src_sel,
258 					DTBCLK_P3_EN, 1);
259 		break;
260 	default:
261 		BREAK_TO_DEBUGGER();
262 		return;
263 	}
264 
265 }
266 
dccg401_set_physymclk(struct dccg * dccg,int phy_inst,enum physymclk_clock_source clk_src,bool force_enable)267 void dccg401_set_physymclk(
268 		struct dccg *dccg,
269 		int phy_inst,
270 		enum physymclk_clock_source clk_src,
271 		bool force_enable)
272 {
273 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
274 
275 	/* Force PHYSYMCLK on and Select phyd32clk as the source of clock which is output to PHY through DCIO */
276 	switch (phy_inst) {
277 	case 0:
278 		if (force_enable) {
279 			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
280 					PHYASYMCLK_EN, 1,
281 					PHYASYMCLK_SRC_SEL, clk_src);
282 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
283 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
284 					PHYASYMCLK_ROOT_GATE_DISABLE, 1);
285 		} else {
286 			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
287 					PHYASYMCLK_EN, 0,
288 					PHYASYMCLK_SRC_SEL, 0);
289 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
290 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
291 					PHYASYMCLK_ROOT_GATE_DISABLE, 0);
292 		}
293 		break;
294 	case 1:
295 		if (force_enable) {
296 			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
297 					PHYBSYMCLK_EN, 1,
298 					PHYBSYMCLK_SRC_SEL, clk_src);
299 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
300 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
301 					PHYBSYMCLK_ROOT_GATE_DISABLE, 1);
302 		} else {
303 			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
304 					PHYBSYMCLK_EN, 0,
305 					PHYBSYMCLK_SRC_SEL, 0);
306 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
307 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
308 					PHYBSYMCLK_ROOT_GATE_DISABLE, 0);
309 		}
310 		break;
311 	case 2:
312 		if (force_enable) {
313 			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
314 					PHYCSYMCLK_EN, 1,
315 					PHYCSYMCLK_SRC_SEL, clk_src);
316 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
317 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
318 					PHYCSYMCLK_ROOT_GATE_DISABLE, 1);
319 		} else {
320 			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
321 					PHYCSYMCLK_EN, 0,
322 					PHYCSYMCLK_SRC_SEL, 0);
323 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
324 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
325 					PHYCSYMCLK_ROOT_GATE_DISABLE, 0);
326 		}
327 		break;
328 	case 3:
329 		if (force_enable) {
330 			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
331 					PHYDSYMCLK_EN, 1,
332 					PHYDSYMCLK_SRC_SEL, clk_src);
333 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
334 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
335 					PHYDSYMCLK_ROOT_GATE_DISABLE, 1);
336 		} else {
337 			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
338 					PHYDSYMCLK_EN, 0,
339 					PHYDSYMCLK_SRC_SEL, 0);
340 			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
341 				REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
342 					PHYDSYMCLK_ROOT_GATE_DISABLE, 0);
343 		}
344 		break;
345 	default:
346 		BREAK_TO_DEBUGGER();
347 		return;
348 	}
349 }
350 
dccg401_get_dccg_ref_freq(struct dccg * dccg,unsigned int xtalin_freq_inKhz,unsigned int * dccg_ref_freq_inKhz)351 static void dccg401_get_dccg_ref_freq(struct dccg *dccg,
352 		unsigned int xtalin_freq_inKhz,
353 		unsigned int *dccg_ref_freq_inKhz)
354 {
355 	/*
356 	 * Assume refclk is sourced from xtalin
357 	 * expect 100MHz
358 	 */
359 	*dccg_ref_freq_inKhz = xtalin_freq_inKhz;
360 	return;
361 }
362 
dccg401_otg_add_pixel(struct dccg * dccg,uint32_t otg_inst)363 static void dccg401_otg_add_pixel(struct dccg *dccg,
364 		uint32_t otg_inst)
365 {
366 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
367 
368 	REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
369 			OTG_ADD_PIXEL[otg_inst], 1);
370 }
371 
dccg401_otg_drop_pixel(struct dccg * dccg,uint32_t otg_inst)372 static void dccg401_otg_drop_pixel(struct dccg *dccg,
373 		uint32_t otg_inst)
374 {
375 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
376 
377 	REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
378 			OTG_DROP_PIXEL[otg_inst], 1);
379 }
380 
dccg401_enable_symclk32_le(struct dccg * dccg,int hpo_le_inst,enum phyd32clk_clock_source phyd32clk)381 static void dccg401_enable_symclk32_le(
382 		struct dccg *dccg,
383 		int hpo_le_inst,
384 		enum phyd32clk_clock_source phyd32clk)
385 {
386 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
387 
388 	/* select one of the PHYD32CLKs as the source for symclk32_le */
389 	switch (hpo_le_inst) {
390 	case 0:
391 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
392 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
393 					SYMCLK32_LE0_GATE_DISABLE, 1,
394 					SYMCLK32_ROOT_LE0_GATE_DISABLE, 1);
395 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
396 				SYMCLK32_LE0_SRC_SEL, phyd32clk,
397 				SYMCLK32_LE0_EN, 1);
398 		break;
399 	case 1:
400 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
401 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
402 					SYMCLK32_LE1_GATE_DISABLE, 1,
403 					SYMCLK32_ROOT_LE1_GATE_DISABLE, 1);
404 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
405 				SYMCLK32_LE1_SRC_SEL, phyd32clk,
406 				SYMCLK32_LE1_EN, 1);
407 		break;
408 	case 2:
409 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
410 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
411 					SYMCLK32_LE2_GATE_DISABLE, 1,
412 					SYMCLK32_ROOT_LE2_GATE_DISABLE, 1);
413 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
414 				SYMCLK32_LE2_SRC_SEL, phyd32clk,
415 				SYMCLK32_LE2_EN, 1);
416 		break;
417 	case 3:
418 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
419 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
420 					SYMCLK32_LE3_GATE_DISABLE, 1,
421 					SYMCLK32_ROOT_LE3_GATE_DISABLE, 1);
422 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
423 				SYMCLK32_LE3_SRC_SEL, phyd32clk,
424 				SYMCLK32_LE3_EN, 1);
425 		break;
426 	default:
427 		BREAK_TO_DEBUGGER();
428 		return;
429 	}
430 }
431 
dccg401_disable_symclk32_le(struct dccg * dccg,int hpo_le_inst)432 static void dccg401_disable_symclk32_le(
433 		struct dccg *dccg,
434 		int hpo_le_inst)
435 {
436 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
437 
438 	/* set refclk as the source for symclk32_le */
439 	switch (hpo_le_inst) {
440 	case 0:
441 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
442 				SYMCLK32_LE0_SRC_SEL, 0,
443 				SYMCLK32_LE0_EN, 0);
444 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
445 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
446 					SYMCLK32_LE0_GATE_DISABLE, 0,
447 					SYMCLK32_ROOT_LE0_GATE_DISABLE, 0);
448 		break;
449 	case 1:
450 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
451 				SYMCLK32_LE1_SRC_SEL, 0,
452 				SYMCLK32_LE1_EN, 0);
453 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
454 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
455 					SYMCLK32_LE1_GATE_DISABLE, 0,
456 					SYMCLK32_ROOT_LE1_GATE_DISABLE, 0);
457 		break;
458 	case 2:
459 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
460 				SYMCLK32_LE2_SRC_SEL, 0,
461 				SYMCLK32_LE2_EN, 0);
462 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
463 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
464 					SYMCLK32_LE2_GATE_DISABLE, 0,
465 					SYMCLK32_ROOT_LE2_GATE_DISABLE, 0);
466 		break;
467 	case 3:
468 		REG_UPDATE_2(SYMCLK32_LE_CNTL,
469 				SYMCLK32_LE3_SRC_SEL, 0,
470 				SYMCLK32_LE3_EN, 0);
471 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
472 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
473 					SYMCLK32_LE3_GATE_DISABLE, 0,
474 					SYMCLK32_ROOT_LE3_GATE_DISABLE, 0);
475 		break;
476 	default:
477 		BREAK_TO_DEBUGGER();
478 		return;
479 	}
480 }
481 
dccg401_enable_dpstreamclk(struct dccg * dccg,int otg_inst,int dp_hpo_inst)482 static void dccg401_enable_dpstreamclk(struct dccg *dccg, int otg_inst, int dp_hpo_inst)
483 {
484 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
485 
486 	/* enabled to select one of the DTBCLKs for pipe */
487 	switch (dp_hpo_inst) {
488 	case 0:
489 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
490 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
491 					DPSTREAMCLK0_ROOT_GATE_DISABLE, 1,
492 					DPSTREAMCLK0_GATE_DISABLE, 1);
493 		REG_UPDATE_2(DPSTREAMCLK_CNTL,
494 				DPSTREAMCLK0_SRC_SEL, otg_inst,
495 				DPSTREAMCLK0_EN, 1);
496 		break;
497 	case 1:
498 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
499 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
500 					DPSTREAMCLK1_ROOT_GATE_DISABLE, 1,
501 					DPSTREAMCLK1_GATE_DISABLE, 1);
502 		REG_UPDATE_2(DPSTREAMCLK_CNTL,
503 				DPSTREAMCLK1_SRC_SEL, otg_inst,
504 				DPSTREAMCLK1_EN, 1);
505 		break;
506 	case 2:
507 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
508 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
509 					DPSTREAMCLK2_ROOT_GATE_DISABLE, 1,
510 					DPSTREAMCLK2_GATE_DISABLE, 1);
511 		REG_UPDATE_2(DPSTREAMCLK_CNTL,
512 				DPSTREAMCLK2_SRC_SEL, otg_inst,
513 				DPSTREAMCLK2_EN, 1);
514 		break;
515 	case 3:
516 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
517 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
518 					DPSTREAMCLK3_ROOT_GATE_DISABLE, 1,
519 					DPSTREAMCLK3_GATE_DISABLE, 1);
520 		REG_UPDATE_2(DPSTREAMCLK_CNTL,
521 				DPSTREAMCLK3_SRC_SEL, otg_inst,
522 				DPSTREAMCLK3_EN, 1);
523 		break;
524 	default:
525 		BREAK_TO_DEBUGGER();
526 		return;
527 	}
528 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
529 		REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3,
530 			DPSTREAMCLK_GATE_DISABLE, 1,
531 			DPSTREAMCLK_ROOT_GATE_DISABLE, 1);
532 }
533 
dccg401_disable_dpstreamclk(struct dccg * dccg,int dp_hpo_inst)534 static void dccg401_disable_dpstreamclk(struct dccg *dccg, int dp_hpo_inst)
535 {
536 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
537 
538 	switch (dp_hpo_inst) {
539 	case 0:
540 		REG_UPDATE(DPSTREAMCLK_CNTL,
541 				DPSTREAMCLK0_EN, 0);
542 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
543 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
544 					DPSTREAMCLK0_ROOT_GATE_DISABLE, 0,
545 					DPSTREAMCLK0_GATE_DISABLE, 0);
546 		break;
547 	case 1:
548 		REG_UPDATE(DPSTREAMCLK_CNTL,
549 				DPSTREAMCLK1_EN, 0);
550 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
551 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
552 					DPSTREAMCLK1_ROOT_GATE_DISABLE, 0,
553 					DPSTREAMCLK1_GATE_DISABLE, 0);
554 		break;
555 	case 2:
556 		REG_UPDATE(DPSTREAMCLK_CNTL,
557 				DPSTREAMCLK2_EN, 0);
558 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
559 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
560 					DPSTREAMCLK2_ROOT_GATE_DISABLE, 0,
561 					DPSTREAMCLK2_GATE_DISABLE, 0);
562 		break;
563 	case 3:
564 		REG_UPDATE(DPSTREAMCLK_CNTL,
565 				DPSTREAMCLK3_EN, 0);
566 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
567 			REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL5,
568 					DPSTREAMCLK3_ROOT_GATE_DISABLE, 0,
569 					DPSTREAMCLK3_GATE_DISABLE, 0);
570 		break;
571 	default:
572 		BREAK_TO_DEBUGGER();
573 		return;
574 	}
575 }
576 
dccg401_set_dpstreamclk(struct dccg * dccg,enum streamclk_source src,int otg_inst,int dp_hpo_inst)577 static void dccg401_set_dpstreamclk(
578 		struct dccg *dccg,
579 		enum streamclk_source src,
580 		int otg_inst,
581 		int dp_hpo_inst)
582 {
583 	/* set the dtbclk_p source */
584 	dccg401_set_dtbclk_p_src(dccg, src, otg_inst);
585 
586 	/* enabled to select one of the DTBCLKs for pipe */
587 	if (src == REFCLK)
588 		dccg401_disable_dpstreamclk(dccg, dp_hpo_inst);
589 	else
590 		dccg401_enable_dpstreamclk(dccg, otg_inst, dp_hpo_inst);
591 }
592 
dccg401_set_dp_dto(struct dccg * dccg,const struct dp_dto_params * params)593 static void dccg401_set_dp_dto(
594 		struct dccg *dccg,
595 		const struct dp_dto_params *params)
596 {
597 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
598 
599 	bool enable = false;
600 
601 	if (params->otg_inst > 3) {
602 		/* dcn401 only has 4 instances */
603 		BREAK_TO_DEBUGGER();
604 		return;
605 	}
606 	if (!params->refclk_hz) {
607 		BREAK_TO_DEBUGGER();
608 		return;
609 	}
610 
611 	if (!dc_is_tmds_signal(params->signal)) {
612 		uint64_t dto_integer;
613 		uint64_t dto_phase_hz;
614 		uint64_t dto_modulo_hz = params->refclk_hz;
615 
616 		enable = true;
617 
618 		/* Set DTO values:
619 		 * int = target_pix_rate / reference_clock
620 		 * phase = target_pix_rate - int * reference_clock,
621 		 * modulo = reference_clock */
622 		dto_integer = div_u64(params->pixclk_hz, dto_modulo_hz);
623 		dto_phase_hz = params->pixclk_hz - dto_integer * dto_modulo_hz;
624 
625 		if (dto_phase_hz <= 0) {
626 			/* negative pixel rate should never happen */
627 			BREAK_TO_DEBUGGER();
628 			return;
629 		}
630 
631 		switch (params->otg_inst) {
632 		case 0:
633 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, 1);
634 			REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL3,
635 					SYMCLK32_SE0_GATE_DISABLE, 1,
636 					SYMCLK32_ROOT_SE0_GATE_DISABLE, 1,
637 					SYMCLK32_LE0_GATE_DISABLE, 1,
638 					SYMCLK32_ROOT_LE0_GATE_DISABLE, 1);
639 			break;
640 		case 1:
641 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, 1);
642 			REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL3,
643 					SYMCLK32_SE1_GATE_DISABLE, 1,
644 					SYMCLK32_ROOT_SE1_GATE_DISABLE, 1,
645 					SYMCLK32_LE1_GATE_DISABLE, 1,
646 					SYMCLK32_ROOT_LE1_GATE_DISABLE, 1);
647 			break;
648 		case 2:
649 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P2_GATE_DISABLE, 1);
650 			REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL3,
651 					SYMCLK32_SE2_GATE_DISABLE, 1,
652 					SYMCLK32_ROOT_SE2_GATE_DISABLE, 1,
653 					SYMCLK32_LE2_GATE_DISABLE, 1,
654 					SYMCLK32_ROOT_LE2_GATE_DISABLE, 1);
655 			break;
656 		case 3:
657 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P3_GATE_DISABLE, 1);
658 			REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL3,
659 					SYMCLK32_SE3_GATE_DISABLE, 1,
660 					SYMCLK32_ROOT_SE3_GATE_DISABLE, 1,
661 					SYMCLK32_LE3_GATE_DISABLE, 1,
662 					SYMCLK32_ROOT_LE3_GATE_DISABLE, 1);
663 			break;
664 		}
665 
666 		dccg401_set_dtbclk_p_src(dccg, params->clk_src, params->otg_inst);
667 
668 		REG_WRITE(DP_DTO_PHASE[params->otg_inst], dto_phase_hz);
669 		REG_WRITE(DP_DTO_MODULO[params->otg_inst], dto_modulo_hz);
670 
671 		switch (params->otg_inst) {
672 		case 0:
673 			REG_UPDATE(OTG_PIXEL_RATE_DIV,
674 					DPDTO0_INT, dto_integer);
675 			break;
676 		case 1:
677 			REG_UPDATE(OTG_PIXEL_RATE_DIV,
678 					DPDTO1_INT, dto_integer);
679 			break;
680 		case 2:
681 			REG_UPDATE(OTG_PIXEL_RATE_DIV,
682 					DPDTO2_INT, dto_integer);
683 			break;
684 		case 3:
685 			REG_UPDATE(OTG_PIXEL_RATE_DIV,
686 					DPDTO3_INT, dto_integer);
687 			break;
688 		default:
689 			BREAK_TO_DEBUGGER();
690 			return;
691 		}
692 	}
693 
694 	/* Toggle DTO */
695 	REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
696 			DP_DTO_ENABLE[params->otg_inst], enable,
697 			PIPE_DTO_SRC_SEL[params->otg_inst], enable);
698 }
699 
dccg401_init(struct dccg * dccg)700 void dccg401_init(struct dccg *dccg)
701 {
702 	/* Set HPO stream encoder to use refclk to avoid case where PHY is
703 	 * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which
704 	 * will cause DCN to hang.
705 	 */
706 	dccg31_disable_symclk32_se(dccg, 0);
707 	dccg31_disable_symclk32_se(dccg, 1);
708 	dccg31_disable_symclk32_se(dccg, 2);
709 	dccg31_disable_symclk32_se(dccg, 3);
710 
711 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) {
712 		dccg401_disable_symclk32_le(dccg, 0);
713 		dccg401_disable_symclk32_le(dccg, 1);
714 		dccg401_disable_symclk32_le(dccg, 2);
715 		dccg401_disable_symclk32_le(dccg, 3);
716 	}
717 
718 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) {
719 		dccg401_disable_dpstreamclk(dccg, 0);
720 		dccg401_disable_dpstreamclk(dccg, 1);
721 		dccg401_disable_dpstreamclk(dccg, 2);
722 		dccg401_disable_dpstreamclk(dccg, 3);
723 	}
724 
725 	if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) {
726 		dccg401_set_physymclk(dccg, 0, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
727 		dccg401_set_physymclk(dccg, 1, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
728 		dccg401_set_physymclk(dccg, 2, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
729 		dccg401_set_physymclk(dccg, 3, PHYSYMCLK_FORCE_SRC_SYMCLK, false);
730 	}
731 }
732 
dccg401_set_dto_dscclk(struct dccg * dccg,uint32_t inst)733 static void dccg401_set_dto_dscclk(struct dccg *dccg, uint32_t inst)
734 {
735 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
736 
737 	switch (inst) {
738 	case 0:
739 		REG_UPDATE_2(DSCCLK0_DTO_PARAM,
740 				DSCCLK0_DTO_PHASE, 1,
741 				DSCCLK0_DTO_MODULO, 1);
742 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, 1);
743 
744 		break;
745 	case 1:
746 		REG_UPDATE_2(DSCCLK1_DTO_PARAM,
747 				DSCCLK1_DTO_PHASE, 1,
748 				DSCCLK1_DTO_MODULO, 1);
749 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 1);
750 		break;
751 	case 2:
752 		REG_UPDATE_2(DSCCLK2_DTO_PARAM,
753 				DSCCLK2_DTO_PHASE, 1,
754 				DSCCLK2_DTO_MODULO, 1);
755 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 1);
756 		break;
757 	case 3:
758 		REG_UPDATE_2(DSCCLK3_DTO_PARAM,
759 				DSCCLK3_DTO_PHASE, 1,
760 				DSCCLK3_DTO_MODULO, 1);
761 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, 1);
762 		break;
763 	default:
764 		BREAK_TO_DEBUGGER();
765 		return;
766 	}
767 }
768 
dccg401_set_ref_dscclk(struct dccg * dccg,uint32_t dsc_inst)769 static void dccg401_set_ref_dscclk(struct dccg *dccg,
770 				uint32_t dsc_inst)
771 {
772 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
773 
774 	switch (dsc_inst) {
775 	case 0:
776 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, 0);
777 		REG_UPDATE_2(DSCCLK0_DTO_PARAM,
778 				DSCCLK0_DTO_PHASE, 0,
779 				DSCCLK0_DTO_MODULO, 0);
780 		break;
781 	case 1:
782 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 0);
783 		REG_UPDATE_2(DSCCLK1_DTO_PARAM,
784 				DSCCLK1_DTO_PHASE, 0,
785 				DSCCLK1_DTO_MODULO, 0);
786 		break;
787 	case 2:
788 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 0);
789 		REG_UPDATE_2(DSCCLK2_DTO_PARAM,
790 				DSCCLK2_DTO_PHASE, 0,
791 				DSCCLK2_DTO_MODULO, 0);
792 		break;
793 	case 3:
794 		REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK3_EN, 0);
795 		REG_UPDATE_2(DSCCLK3_DTO_PARAM,
796 				DSCCLK3_DTO_PHASE, 0,
797 				DSCCLK3_DTO_MODULO, 0);
798 		break;
799 	default:
800 		return;
801 	}
802 }
803 
dccg401_enable_symclk_se(struct dccg * dccg,uint32_t stream_enc_inst,uint32_t link_enc_inst)804 static void dccg401_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
805 {
806 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
807 
808 	switch (link_enc_inst) {
809 	case 0:
810 		REG_UPDATE(SYMCLKA_CLOCK_ENABLE,
811 				SYMCLKA_CLOCK_ENABLE, 1);
812 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
813 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_ROOT_GATE_DISABLE, 1);
814 		break;
815 	case 1:
816 		REG_UPDATE(SYMCLKB_CLOCK_ENABLE,
817 				SYMCLKB_CLOCK_ENABLE, 1);
818 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
819 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_ROOT_GATE_DISABLE, 1);
820 		break;
821 	case 2:
822 		REG_UPDATE(SYMCLKC_CLOCK_ENABLE,
823 				SYMCLKC_CLOCK_ENABLE, 1);
824 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
825 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_ROOT_GATE_DISABLE, 1);
826 		break;
827 	case 3:
828 		REG_UPDATE(SYMCLKD_CLOCK_ENABLE,
829 				SYMCLKD_CLOCK_ENABLE, 1);
830 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
831 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_ROOT_GATE_DISABLE, 1);
832 		break;
833 	}
834 
835 	switch (stream_enc_inst) {
836 	case 0:
837 		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,
838 				SYMCLKA_FE_EN, 1,
839 				SYMCLKA_FE_SRC_SEL, link_enc_inst);
840 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
841 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_FE_ROOT_GATE_DISABLE, 1);
842 		break;
843 	case 1:
844 		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,
845 				SYMCLKB_FE_EN, 1,
846 				SYMCLKB_FE_SRC_SEL, link_enc_inst);
847 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
848 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_FE_ROOT_GATE_DISABLE, 1);
849 		break;
850 	case 2:
851 		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,
852 				SYMCLKC_FE_EN, 1,
853 				SYMCLKC_FE_SRC_SEL, link_enc_inst);
854 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
855 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_FE_ROOT_GATE_DISABLE, 1);
856 		break;
857 	case 3:
858 		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,
859 				SYMCLKD_FE_EN, 1,
860 				SYMCLKD_FE_SRC_SEL, link_enc_inst);
861 		if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
862 			REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_FE_ROOT_GATE_DISABLE, 1);
863 		break;
864 	}
865 }
866 
867 /*get other front end connected to this backend*/
dccg401_get_number_enabled_symclk_fe_connected_to_be(struct dccg * dccg,uint32_t link_enc_inst)868 static uint8_t dccg401_get_number_enabled_symclk_fe_connected_to_be(struct dccg *dccg, uint32_t link_enc_inst)
869 {
870 	uint8_t num_enabled_symclk_fe = 0;
871 	uint32_t fe_clk_en[4] = {0}, be_clk_sel[4] = {0};
872 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
873 	uint8_t i;
874 
875 	REG_GET_2(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_EN, &fe_clk_en[0],
876 			SYMCLKA_FE_SRC_SEL, &be_clk_sel[0]);
877 
878 	REG_GET_2(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_EN, &fe_clk_en[1],
879 			SYMCLKB_FE_SRC_SEL, &be_clk_sel[1]);
880 
881 	REG_GET_2(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_EN, &fe_clk_en[2],
882 			SYMCLKC_FE_SRC_SEL, &be_clk_sel[2]);
883 
884 	REG_GET_2(SYMCLKD_CLOCK_ENABLE,	SYMCLKD_FE_EN, &fe_clk_en[3],
885 			SYMCLKD_FE_SRC_SEL, &be_clk_sel[3]);
886 
887 	for (i = 0; i < ARRAY_SIZE(fe_clk_en); i++) {
888 		if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst)
889 			num_enabled_symclk_fe++;
890 	}
891 
892 	return num_enabled_symclk_fe;
893 }
894 
dccg401_disable_symclk_se(struct dccg * dccg,uint32_t stream_enc_inst,uint32_t link_enc_inst)895 static void dccg401_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
896 {
897 	uint8_t num_enabled_symclk_fe = 0;
898 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
899 
900 	switch (stream_enc_inst) {
901 	case 0:
902 		REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,
903 				SYMCLKA_FE_EN, 0,
904 				SYMCLKA_FE_SRC_SEL, 0);
905 		break;
906 	case 1:
907 		REG_UPDATE_2(SYMCLKB_CLOCK_ENABLE,
908 				SYMCLKB_FE_EN, 0,
909 				SYMCLKB_FE_SRC_SEL, 0);
910 		break;
911 	case 2:
912 		REG_UPDATE_2(SYMCLKC_CLOCK_ENABLE,
913 				SYMCLKC_FE_EN, 0,
914 				SYMCLKC_FE_SRC_SEL, 0);
915 		break;
916 	case 3:
917 		REG_UPDATE_2(SYMCLKD_CLOCK_ENABLE,
918 				SYMCLKD_FE_EN, 0,
919 				SYMCLKD_FE_SRC_SEL, 0);
920 		break;
921 	}
922 
923 	/*check other enabled symclk fe connected to this be */
924 	num_enabled_symclk_fe = dccg401_get_number_enabled_symclk_fe_connected_to_be(dccg, link_enc_inst);
925 	/*only turn off backend clk if other front ends attached to this backend are all off,
926 	 for mst, only turn off the backend if this is the last front end*/
927 	if (num_enabled_symclk_fe == 0) {
928 		switch (link_enc_inst) {
929 		case 0:
930 			REG_UPDATE(SYMCLKA_CLOCK_ENABLE,
931 					SYMCLKA_CLOCK_ENABLE, 0);
932 			break;
933 		case 1:
934 			REG_UPDATE(SYMCLKB_CLOCK_ENABLE,
935 					SYMCLKB_CLOCK_ENABLE, 0);
936 			break;
937 		case 2:
938 			REG_UPDATE(SYMCLKC_CLOCK_ENABLE,
939 					SYMCLKC_CLOCK_ENABLE, 0);
940 			break;
941 		case 3:
942 			REG_UPDATE(SYMCLKD_CLOCK_ENABLE,
943 					SYMCLKD_CLOCK_ENABLE, 0);
944 			break;
945 		}
946 	}
947 }
948 
949 static const struct dccg_funcs dccg401_funcs = {
950 	.update_dpp_dto = dccg401_update_dpp_dto,
951 	.get_dccg_ref_freq = dccg401_get_dccg_ref_freq,
952 	.dccg_init = dccg401_init,
953 	.set_dpstreamclk = dccg401_set_dpstreamclk,
954 	.enable_symclk32_se = dccg31_enable_symclk32_se,
955 	.disable_symclk32_se = dccg31_disable_symclk32_se,
956 	.enable_symclk32_le = dccg401_enable_symclk32_le,
957 	.disable_symclk32_le = dccg401_disable_symclk32_le,
958 	.set_physymclk = dccg401_set_physymclk,
959 	.set_dtbclk_dto = NULL,
960 	.set_dto_dscclk = dccg401_set_dto_dscclk,
961 	.set_ref_dscclk = dccg401_set_ref_dscclk,
962 	.set_valid_pixel_rate = NULL,
963 	.set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
964 	.set_audio_dtbclk_dto = NULL,
965 	.otg_add_pixel = dccg401_otg_add_pixel,
966 	.otg_drop_pixel = dccg401_otg_drop_pixel,
967 	.set_pixel_rate_div = dccg401_set_pixel_rate_div,
968 	.get_pixel_rate_div = dccg401_get_pixel_rate_div,
969 	.set_dp_dto = dccg401_set_dp_dto,
970 	.enable_symclk_se = dccg401_enable_symclk_se,
971 	.disable_symclk_se = dccg401_disable_symclk_se,
972 	.set_dtbclk_p_src = dccg401_set_dtbclk_p_src,
973 };
974 
dccg401_create(struct dc_context * ctx,const struct dccg_registers * regs,const struct dccg_shift * dccg_shift,const struct dccg_mask * dccg_mask)975 struct dccg *dccg401_create(
976 	struct dc_context *ctx,
977 	const struct dccg_registers *regs,
978 	const struct dccg_shift *dccg_shift,
979 	const struct dccg_mask *dccg_mask)
980 {
981 	struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
982 	struct dccg *base;
983 
984 	if (dccg_dcn == NULL) {
985 		BREAK_TO_DEBUGGER();
986 		return NULL;
987 	}
988 
989 	base = &dccg_dcn->base;
990 	base->ctx = ctx;
991 	base->funcs = &dccg401_funcs;
992 
993 	dccg_dcn->regs = regs;
994 	dccg_dcn->dccg_shift = dccg_shift;
995 	dccg_dcn->dccg_mask = dccg_mask;
996 
997 	return &dccg_dcn->base;
998 }
999