1 /* 2 * Copyright 2018 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 #include "reg_helper.h" 27 #include "core_types.h" 28 #include "dcn31_dccg.h" 29 #include "dal_asic_id.h" 30 31 #define TO_DCN_DCCG(dccg)\ 32 container_of(dccg, struct dcn_dccg, base) 33 34 #define REG(reg) \ 35 (dccg_dcn->regs->reg) 36 37 #undef FN 38 #define FN(reg_name, field_name) \ 39 dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name 40 41 #define CTX \ 42 dccg_dcn->base.ctx 43 #define DC_LOGGER \ 44 dccg->ctx->logger 45 46 static void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk) 47 { 48 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 49 50 if (dccg->ref_dppclk && req_dppclk) { 51 int ref_dppclk = dccg->ref_dppclk; 52 int modulo, phase; 53 54 // phase / modulo = dpp pipe clk / dpp global clk 55 modulo = 0xff; // use FF at the end 56 phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk; 57 58 if (phase > 0xff) { 59 ASSERT(false); 60 phase = 0xff; 61 } 62 63 REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, 64 DPPCLK0_DTO_PHASE, phase, 65 DPPCLK0_DTO_MODULO, modulo); 66 REG_UPDATE(DPPCLK_DTO_CTRL, 67 DPPCLK_DTO_ENABLE[dpp_inst], 1); 68 } else { 69 //DTO must be enabled to generate a 0Hz clock output 70 if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) { 71 REG_UPDATE(DPPCLK_DTO_CTRL, 72 DPPCLK_DTO_ENABLE[dpp_inst], 1); 73 REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, 74 DPPCLK0_DTO_PHASE, 0, 75 DPPCLK0_DTO_MODULO, 1); 76 } else { 77 REG_UPDATE(DPPCLK_DTO_CTRL, 78 DPPCLK_DTO_ENABLE[dpp_inst], 0); 79 } 80 } 81 dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk; 82 } 83 84 static enum phyd32clk_clock_source get_phy_mux_symclk( 85 struct dcn_dccg *dccg_dcn, 86 enum phyd32clk_clock_source src) 87 { 88 if (dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { 89 if (src == PHYD32CLKC) 90 src = PHYD32CLKF; 91 if (src == PHYD32CLKD) 92 src = PHYD32CLKG; 93 } 94 return src; 95 } 96 97 static void dccg31_enable_dpstreamclk(struct dccg *dccg, int otg_inst) 98 { 99 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 100 101 /* enabled to select one of the DTBCLKs for pipe */ 102 switch (otg_inst) { 103 case 0: 104 REG_UPDATE(DPSTREAMCLK_CNTL, 105 DPSTREAMCLK_PIPE0_EN, 1); 106 break; 107 case 1: 108 REG_UPDATE(DPSTREAMCLK_CNTL, 109 DPSTREAMCLK_PIPE1_EN, 1); 110 break; 111 case 2: 112 REG_UPDATE(DPSTREAMCLK_CNTL, 113 DPSTREAMCLK_PIPE2_EN, 1); 114 break; 115 case 3: 116 REG_UPDATE(DPSTREAMCLK_CNTL, 117 DPSTREAMCLK_PIPE3_EN, 1); 118 break; 119 default: 120 BREAK_TO_DEBUGGER(); 121 return; 122 } 123 if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) 124 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 125 DPSTREAMCLK_ROOT_GATE_DISABLE, 1); 126 } 127 128 static void dccg31_disable_dpstreamclk(struct dccg *dccg, int otg_inst) 129 { 130 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 131 132 if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) 133 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 134 DPSTREAMCLK_ROOT_GATE_DISABLE, 0); 135 136 switch (otg_inst) { 137 case 0: 138 REG_UPDATE(DPSTREAMCLK_CNTL, 139 DPSTREAMCLK_PIPE0_EN, 0); 140 break; 141 case 1: 142 REG_UPDATE(DPSTREAMCLK_CNTL, 143 DPSTREAMCLK_PIPE1_EN, 0); 144 break; 145 case 2: 146 REG_UPDATE(DPSTREAMCLK_CNTL, 147 DPSTREAMCLK_PIPE2_EN, 0); 148 break; 149 case 3: 150 REG_UPDATE(DPSTREAMCLK_CNTL, 151 DPSTREAMCLK_PIPE3_EN, 0); 152 break; 153 default: 154 BREAK_TO_DEBUGGER(); 155 return; 156 } 157 } 158 159 void dccg31_set_dpstreamclk( 160 struct dccg *dccg, 161 enum hdmistreamclk_source src, 162 int otg_inst) 163 { 164 if (src == REFCLK) 165 dccg31_disable_dpstreamclk(dccg, otg_inst); 166 else 167 dccg31_enable_dpstreamclk(dccg, otg_inst); 168 } 169 170 void dccg31_enable_symclk32_se( 171 struct dccg *dccg, 172 int hpo_se_inst, 173 enum phyd32clk_clock_source phyd32clk) 174 { 175 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 176 177 phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk); 178 179 /* select one of the PHYD32CLKs as the source for symclk32_se */ 180 switch (hpo_se_inst) { 181 case 0: 182 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 183 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 184 SYMCLK32_ROOT_SE0_GATE_DISABLE, 1); 185 REG_UPDATE_2(SYMCLK32_SE_CNTL, 186 SYMCLK32_SE0_SRC_SEL, phyd32clk, 187 SYMCLK32_SE0_EN, 1); 188 break; 189 case 1: 190 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 191 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 192 SYMCLK32_ROOT_SE1_GATE_DISABLE, 1); 193 REG_UPDATE_2(SYMCLK32_SE_CNTL, 194 SYMCLK32_SE1_SRC_SEL, phyd32clk, 195 SYMCLK32_SE1_EN, 1); 196 break; 197 case 2: 198 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 199 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 200 SYMCLK32_ROOT_SE2_GATE_DISABLE, 1); 201 REG_UPDATE_2(SYMCLK32_SE_CNTL, 202 SYMCLK32_SE2_SRC_SEL, phyd32clk, 203 SYMCLK32_SE2_EN, 1); 204 break; 205 case 3: 206 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 207 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 208 SYMCLK32_ROOT_SE3_GATE_DISABLE, 1); 209 REG_UPDATE_2(SYMCLK32_SE_CNTL, 210 SYMCLK32_SE3_SRC_SEL, phyd32clk, 211 SYMCLK32_SE3_EN, 1); 212 break; 213 default: 214 BREAK_TO_DEBUGGER(); 215 return; 216 } 217 } 218 219 void dccg31_disable_symclk32_se( 220 struct dccg *dccg, 221 int hpo_se_inst) 222 { 223 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 224 225 /* set refclk as the source for symclk32_se */ 226 switch (hpo_se_inst) { 227 case 0: 228 REG_UPDATE_2(SYMCLK32_SE_CNTL, 229 SYMCLK32_SE0_SRC_SEL, 0, 230 SYMCLK32_SE0_EN, 0); 231 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 232 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 233 SYMCLK32_ROOT_SE0_GATE_DISABLE, 0); 234 break; 235 case 1: 236 REG_UPDATE_2(SYMCLK32_SE_CNTL, 237 SYMCLK32_SE1_SRC_SEL, 0, 238 SYMCLK32_SE1_EN, 0); 239 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 240 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 241 SYMCLK32_ROOT_SE1_GATE_DISABLE, 0); 242 break; 243 case 2: 244 REG_UPDATE_2(SYMCLK32_SE_CNTL, 245 SYMCLK32_SE2_SRC_SEL, 0, 246 SYMCLK32_SE2_EN, 0); 247 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 248 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 249 SYMCLK32_ROOT_SE2_GATE_DISABLE, 0); 250 break; 251 case 3: 252 REG_UPDATE_2(SYMCLK32_SE_CNTL, 253 SYMCLK32_SE3_SRC_SEL, 0, 254 SYMCLK32_SE3_EN, 0); 255 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 256 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 257 SYMCLK32_ROOT_SE3_GATE_DISABLE, 0); 258 break; 259 default: 260 BREAK_TO_DEBUGGER(); 261 return; 262 } 263 } 264 265 void dccg31_enable_symclk32_le( 266 struct dccg *dccg, 267 int hpo_le_inst, 268 enum phyd32clk_clock_source phyd32clk) 269 { 270 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 271 272 phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk); 273 274 /* select one of the PHYD32CLKs as the source for symclk32_le */ 275 switch (hpo_le_inst) { 276 case 0: 277 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) 278 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 279 SYMCLK32_ROOT_LE0_GATE_DISABLE, 1); 280 REG_UPDATE_2(SYMCLK32_LE_CNTL, 281 SYMCLK32_LE0_SRC_SEL, phyd32clk, 282 SYMCLK32_LE0_EN, 1); 283 break; 284 case 1: 285 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) 286 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 287 SYMCLK32_ROOT_LE1_GATE_DISABLE, 1); 288 REG_UPDATE_2(SYMCLK32_LE_CNTL, 289 SYMCLK32_LE1_SRC_SEL, phyd32clk, 290 SYMCLK32_LE1_EN, 1); 291 break; 292 default: 293 BREAK_TO_DEBUGGER(); 294 return; 295 } 296 } 297 298 void dccg31_disable_symclk32_le( 299 struct dccg *dccg, 300 int hpo_le_inst) 301 { 302 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 303 304 /* set refclk as the source for symclk32_le */ 305 switch (hpo_le_inst) { 306 case 0: 307 REG_UPDATE_2(SYMCLK32_LE_CNTL, 308 SYMCLK32_LE0_SRC_SEL, 0, 309 SYMCLK32_LE0_EN, 0); 310 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) 311 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 312 SYMCLK32_ROOT_LE0_GATE_DISABLE, 0); 313 break; 314 case 1: 315 REG_UPDATE_2(SYMCLK32_LE_CNTL, 316 SYMCLK32_LE1_SRC_SEL, 0, 317 SYMCLK32_LE1_EN, 0); 318 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) 319 REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, 320 SYMCLK32_ROOT_LE1_GATE_DISABLE, 0); 321 break; 322 default: 323 BREAK_TO_DEBUGGER(); 324 return; 325 } 326 } 327 328 static void dccg31_disable_dscclk(struct dccg *dccg, int inst) 329 { 330 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 331 332 if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc) 333 return; 334 //DTO must be enabled to generate a 0 Hz clock output 335 switch (inst) { 336 case 0: 337 REG_UPDATE(DSCCLK_DTO_CTRL, 338 DSCCLK0_DTO_ENABLE, 1); 339 REG_UPDATE_2(DSCCLK0_DTO_PARAM, 340 DSCCLK0_DTO_PHASE, 0, 341 DSCCLK0_DTO_MODULO, 1); 342 break; 343 case 1: 344 REG_UPDATE(DSCCLK_DTO_CTRL, 345 DSCCLK1_DTO_ENABLE, 1); 346 REG_UPDATE_2(DSCCLK1_DTO_PARAM, 347 DSCCLK1_DTO_PHASE, 0, 348 DSCCLK1_DTO_MODULO, 1); 349 break; 350 case 2: 351 REG_UPDATE(DSCCLK_DTO_CTRL, 352 DSCCLK2_DTO_ENABLE, 1); 353 REG_UPDATE_2(DSCCLK2_DTO_PARAM, 354 DSCCLK2_DTO_PHASE, 0, 355 DSCCLK2_DTO_MODULO, 1); 356 break; 357 default: 358 BREAK_TO_DEBUGGER(); 359 return; 360 } 361 } 362 363 static void dccg31_enable_dscclk(struct dccg *dccg, int inst) 364 { 365 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 366 367 if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc) 368 return; 369 //Disable DTO 370 switch (inst) { 371 case 0: 372 REG_UPDATE_2(DSCCLK0_DTO_PARAM, 373 DSCCLK0_DTO_PHASE, 0, 374 DSCCLK0_DTO_MODULO, 0); 375 REG_UPDATE(DSCCLK_DTO_CTRL, 376 DSCCLK0_DTO_ENABLE, 0); 377 break; 378 case 1: 379 REG_UPDATE_2(DSCCLK1_DTO_PARAM, 380 DSCCLK1_DTO_PHASE, 0, 381 DSCCLK1_DTO_MODULO, 0); 382 REG_UPDATE(DSCCLK_DTO_CTRL, 383 DSCCLK1_DTO_ENABLE, 0); 384 break; 385 case 2: 386 REG_UPDATE_2(DSCCLK2_DTO_PARAM, 387 DSCCLK2_DTO_PHASE, 0, 388 DSCCLK2_DTO_MODULO, 0); 389 REG_UPDATE(DSCCLK_DTO_CTRL, 390 DSCCLK2_DTO_ENABLE, 0); 391 break; 392 default: 393 BREAK_TO_DEBUGGER(); 394 return; 395 } 396 } 397 398 void dccg31_set_physymclk( 399 struct dccg *dccg, 400 int phy_inst, 401 enum physymclk_clock_source clk_src, 402 bool force_enable) 403 { 404 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 405 406 /* Force PHYSYMCLK on and Select phyd32clk as the source of clock which is output to PHY through DCIO */ 407 switch (phy_inst) { 408 case 0: 409 if (force_enable) 410 REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, 411 PHYASYMCLK_FORCE_EN, 1, 412 PHYASYMCLK_FORCE_SRC_SEL, clk_src); 413 else 414 REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, 415 PHYASYMCLK_FORCE_EN, 0, 416 PHYASYMCLK_FORCE_SRC_SEL, 0); 417 break; 418 case 1: 419 if (force_enable) 420 REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, 421 PHYBSYMCLK_FORCE_EN, 1, 422 PHYBSYMCLK_FORCE_SRC_SEL, clk_src); 423 else 424 REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, 425 PHYBSYMCLK_FORCE_EN, 0, 426 PHYBSYMCLK_FORCE_SRC_SEL, 0); 427 break; 428 case 2: 429 if (force_enable) 430 REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, 431 PHYCSYMCLK_FORCE_EN, 1, 432 PHYCSYMCLK_FORCE_SRC_SEL, clk_src); 433 else 434 REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, 435 PHYCSYMCLK_FORCE_EN, 0, 436 PHYCSYMCLK_FORCE_SRC_SEL, 0); 437 break; 438 case 3: 439 if (force_enable) 440 REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, 441 PHYDSYMCLK_FORCE_EN, 1, 442 PHYDSYMCLK_FORCE_SRC_SEL, clk_src); 443 else 444 REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, 445 PHYDSYMCLK_FORCE_EN, 0, 446 PHYDSYMCLK_FORCE_SRC_SEL, 0); 447 break; 448 case 4: 449 if (force_enable) 450 REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, 451 PHYESYMCLK_FORCE_EN, 1, 452 PHYESYMCLK_FORCE_SRC_SEL, clk_src); 453 else 454 REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, 455 PHYESYMCLK_FORCE_EN, 0, 456 PHYESYMCLK_FORCE_SRC_SEL, 0); 457 break; 458 default: 459 BREAK_TO_DEBUGGER(); 460 return; 461 } 462 } 463 464 /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */ 465 void dccg31_set_dtbclk_dto( 466 struct dccg *dccg, 467 int dtbclk_inst, 468 int req_dtbclk_khz, 469 int num_odm_segments, 470 const struct dc_crtc_timing *timing) 471 { 472 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 473 uint32_t dtbdto_div; 474 475 /* Mode DTBDTO Rate DTBCLK_DTO<x>_DIV Register 476 * ODM 4:1 combine pixel rate/4 2 477 * ODM 2:1 combine pixel rate/2 4 478 * non-DSC 4:2:0 mode pixel rate/2 4 479 * DSC native 4:2:0 pixel rate/2 4 480 * DSC native 4:2:2 pixel rate/2 4 481 * Other modes pixel rate 8 482 */ 483 if (num_odm_segments == 4) { 484 dtbdto_div = 2; 485 req_dtbclk_khz = req_dtbclk_khz / 4; 486 } else if ((num_odm_segments == 2) || 487 (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) || 488 (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422 489 && !timing->dsc_cfg.ycbcr422_simple)) { 490 dtbdto_div = 4; 491 req_dtbclk_khz = req_dtbclk_khz / 2; 492 } else 493 dtbdto_div = 8; 494 495 if (dccg->ref_dtbclk_khz && req_dtbclk_khz) { 496 uint32_t modulo, phase; 497 498 // phase / modulo = dtbclk / dtbclk ref 499 modulo = dccg->ref_dtbclk_khz * 1000; 500 phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + dccg->ref_dtbclk_khz - 1), 501 dccg->ref_dtbclk_khz); 502 503 REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst], 504 DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div); 505 506 REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], modulo); 507 REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], phase); 508 509 REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst], 510 DTBCLK_DTO_ENABLE[dtbclk_inst], 1); 511 512 REG_WAIT(OTG_PIXEL_RATE_CNTL[dtbclk_inst], 513 DTBCLKDTO_ENABLE_STATUS[dtbclk_inst], 1, 514 1, 100); 515 516 /* The recommended programming sequence to enable DTBCLK DTO to generate 517 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should 518 * be set only after DTO is enabled 519 */ 520 REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst], 521 PIPE_DTO_SRC_SEL[dtbclk_inst], 1); 522 523 dccg->dtbclk_khz[dtbclk_inst] = req_dtbclk_khz; 524 } else { 525 REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[dtbclk_inst], 526 DTBCLK_DTO_ENABLE[dtbclk_inst], 0, 527 PIPE_DTO_SRC_SEL[dtbclk_inst], 0, 528 DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div); 529 530 REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], 0); 531 REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], 0); 532 533 dccg->dtbclk_khz[dtbclk_inst] = 0; 534 } 535 } 536 537 void dccg31_set_audio_dtbclk_dto( 538 struct dccg *dccg, 539 uint32_t req_audio_dtbclk_khz) 540 { 541 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 542 543 if (dccg->ref_dtbclk_khz && req_audio_dtbclk_khz) { 544 uint32_t modulo, phase; 545 546 // phase / modulo = dtbclk / dtbclk ref 547 modulo = dccg->ref_dtbclk_khz * 1000; 548 phase = div_u64((((unsigned long long)modulo * req_audio_dtbclk_khz) + dccg->ref_dtbclk_khz - 1), 549 dccg->ref_dtbclk_khz); 550 551 552 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, modulo); 553 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, phase); 554 555 //REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, 556 // DCCG_AUDIO_DTBCLK_DTO_USE_512FBR_DTO, 1); 557 558 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, 559 DCCG_AUDIO_DTO_SEL, 4); // 04 - DCCG_AUDIO_DTO_SEL_AUDIO_DTO_DTBCLK 560 561 dccg->audio_dtbclk_khz = req_audio_dtbclk_khz; 562 } else { 563 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, 0); 564 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, 0); 565 566 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, 567 DCCG_AUDIO_DTO_SEL, 3); // 03 - DCCG_AUDIO_DTO_SEL_NO_AUDIO_DTO 568 569 dccg->audio_dtbclk_khz = 0; 570 } 571 } 572 573 static void dccg31_get_dccg_ref_freq(struct dccg *dccg, 574 unsigned int xtalin_freq_inKhz, 575 unsigned int *dccg_ref_freq_inKhz) 576 { 577 /* 578 * Assume refclk is sourced from xtalin 579 * expect 24MHz 580 */ 581 *dccg_ref_freq_inKhz = xtalin_freq_inKhz; 582 return; 583 } 584 585 static void dccg31_set_dispclk_change_mode( 586 struct dccg *dccg, 587 enum dentist_dispclk_change_mode change_mode) 588 { 589 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 590 591 REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE, 592 change_mode == DISPCLK_CHANGE_MODE_RAMPING ? 2 : 0); 593 } 594 595 void dccg31_init(struct dccg *dccg) 596 { 597 /* Set HPO stream encoder to use refclk to avoid case where PHY is 598 * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which 599 * will cause DCN to hang. 600 */ 601 dccg31_disable_symclk32_se(dccg, 0); 602 dccg31_disable_symclk32_se(dccg, 1); 603 dccg31_disable_symclk32_se(dccg, 2); 604 dccg31_disable_symclk32_se(dccg, 3); 605 606 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) { 607 dccg31_disable_symclk32_le(dccg, 0); 608 dccg31_disable_symclk32_le(dccg, 1); 609 } 610 611 if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) { 612 dccg31_disable_dpstreamclk(dccg, 0); 613 dccg31_disable_dpstreamclk(dccg, 1); 614 dccg31_disable_dpstreamclk(dccg, 2); 615 dccg31_disable_dpstreamclk(dccg, 3); 616 } 617 618 } 619 620 static const struct dccg_funcs dccg31_funcs = { 621 .update_dpp_dto = dccg31_update_dpp_dto, 622 .get_dccg_ref_freq = dccg31_get_dccg_ref_freq, 623 .dccg_init = dccg31_init, 624 .set_dpstreamclk = dccg31_set_dpstreamclk, 625 .enable_symclk32_se = dccg31_enable_symclk32_se, 626 .disable_symclk32_se = dccg31_disable_symclk32_se, 627 .enable_symclk32_le = dccg31_enable_symclk32_le, 628 .disable_symclk32_le = dccg31_disable_symclk32_le, 629 .set_physymclk = dccg31_set_physymclk, 630 .set_dtbclk_dto = dccg31_set_dtbclk_dto, 631 .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto, 632 .set_dispclk_change_mode = dccg31_set_dispclk_change_mode, 633 .disable_dsc = dccg31_disable_dscclk, 634 .enable_dsc = dccg31_enable_dscclk, 635 }; 636 637 struct dccg *dccg31_create( 638 struct dc_context *ctx, 639 const struct dccg_registers *regs, 640 const struct dccg_shift *dccg_shift, 641 const struct dccg_mask *dccg_mask) 642 { 643 struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); 644 struct dccg *base; 645 646 if (dccg_dcn == NULL) { 647 BREAK_TO_DEBUGGER(); 648 return NULL; 649 } 650 651 base = &dccg_dcn->base; 652 base->ctx = ctx; 653 base->funcs = &dccg31_funcs; 654 655 dccg_dcn->regs = regs; 656 dccg_dcn->dccg_shift = dccg_shift; 657 dccg_dcn->dccg_mask = dccg_mask; 658 659 return &dccg_dcn->base; 660 } 661