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