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