MAINTAINERS: update the LSM maintainer info
[platform/kernel/linux-starfive.git] / drivers / gpu / drm / amd / display / dc / dcn31 / dcn31_dccg.c
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 }