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