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 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 REG_UPDATE(DPPCLK_DTO_CTRL, 70 DPPCLK_DTO_ENABLE[dpp_inst], 0); 71 } 72 dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk; 73 } 74 75 static enum phyd32clk_clock_source get_phy_mux_symclk( 76 struct dcn_dccg *dccg_dcn, 77 enum phyd32clk_clock_source src) 78 { 79 if (dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { 80 if (src == PHYD32CLKC) 81 src = PHYD32CLKF; 82 if (src == PHYD32CLKD) 83 src = PHYD32CLKG; 84 } 85 return src; 86 } 87 88 static void dccg31_enable_dpstreamclk(struct dccg *dccg, int otg_inst) 89 { 90 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 91 92 /* enabled to select one of the DTBCLKs for pipe */ 93 switch (otg_inst) { 94 case 0: 95 REG_UPDATE(DPSTREAMCLK_CNTL, 96 DPSTREAMCLK_PIPE0_EN, 1); 97 break; 98 case 1: 99 REG_UPDATE(DPSTREAMCLK_CNTL, 100 DPSTREAMCLK_PIPE1_EN, 1); 101 break; 102 case 2: 103 REG_UPDATE(DPSTREAMCLK_CNTL, 104 DPSTREAMCLK_PIPE2_EN, 1); 105 break; 106 case 3: 107 REG_UPDATE(DPSTREAMCLK_CNTL, 108 DPSTREAMCLK_PIPE3_EN, 1); 109 break; 110 default: 111 BREAK_TO_DEBUGGER(); 112 return; 113 } 114 if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) 115 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 116 DPSTREAMCLK_GATE_DISABLE, 1, 117 DPSTREAMCLK_ROOT_GATE_DISABLE, 1); 118 } 119 120 static void dccg31_disable_dpstreamclk(struct dccg *dccg, int otg_inst) 121 { 122 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 123 124 if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) 125 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 126 DPSTREAMCLK_ROOT_GATE_DISABLE, 0, 127 DPSTREAMCLK_GATE_DISABLE, 0); 128 129 switch (otg_inst) { 130 case 0: 131 REG_UPDATE(DPSTREAMCLK_CNTL, 132 DPSTREAMCLK_PIPE0_EN, 0); 133 break; 134 case 1: 135 REG_UPDATE(DPSTREAMCLK_CNTL, 136 DPSTREAMCLK_PIPE1_EN, 0); 137 break; 138 case 2: 139 REG_UPDATE(DPSTREAMCLK_CNTL, 140 DPSTREAMCLK_PIPE2_EN, 0); 141 break; 142 case 3: 143 REG_UPDATE(DPSTREAMCLK_CNTL, 144 DPSTREAMCLK_PIPE3_EN, 0); 145 break; 146 default: 147 BREAK_TO_DEBUGGER(); 148 return; 149 } 150 } 151 152 void dccg31_set_dpstreamclk( 153 struct dccg *dccg, 154 enum streamclk_source src, 155 int otg_inst, 156 int dp_hpo_inst) 157 { 158 if (src == REFCLK) 159 dccg31_disable_dpstreamclk(dccg, otg_inst); 160 else 161 dccg31_enable_dpstreamclk(dccg, otg_inst); 162 } 163 164 void dccg31_enable_symclk32_se( 165 struct dccg *dccg, 166 int hpo_se_inst, 167 enum phyd32clk_clock_source phyd32clk) 168 { 169 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 170 171 phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk); 172 173 /* select one of the PHYD32CLKs as the source for symclk32_se */ 174 switch (hpo_se_inst) { 175 case 0: 176 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 177 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 178 SYMCLK32_SE0_GATE_DISABLE, 1, 179 SYMCLK32_ROOT_SE0_GATE_DISABLE, 1); 180 REG_UPDATE_2(SYMCLK32_SE_CNTL, 181 SYMCLK32_SE0_SRC_SEL, phyd32clk, 182 SYMCLK32_SE0_EN, 1); 183 break; 184 case 1: 185 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 186 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 187 SYMCLK32_SE1_GATE_DISABLE, 1, 188 SYMCLK32_ROOT_SE1_GATE_DISABLE, 1); 189 REG_UPDATE_2(SYMCLK32_SE_CNTL, 190 SYMCLK32_SE1_SRC_SEL, phyd32clk, 191 SYMCLK32_SE1_EN, 1); 192 break; 193 case 2: 194 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 195 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 196 SYMCLK32_SE2_GATE_DISABLE, 1, 197 SYMCLK32_ROOT_SE2_GATE_DISABLE, 1); 198 REG_UPDATE_2(SYMCLK32_SE_CNTL, 199 SYMCLK32_SE2_SRC_SEL, phyd32clk, 200 SYMCLK32_SE2_EN, 1); 201 break; 202 case 3: 203 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 204 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 205 SYMCLK32_SE3_GATE_DISABLE, 1, 206 SYMCLK32_ROOT_SE3_GATE_DISABLE, 1); 207 REG_UPDATE_2(SYMCLK32_SE_CNTL, 208 SYMCLK32_SE3_SRC_SEL, phyd32clk, 209 SYMCLK32_SE3_EN, 1); 210 break; 211 default: 212 BREAK_TO_DEBUGGER(); 213 return; 214 } 215 } 216 217 void dccg31_disable_symclk32_se( 218 struct dccg *dccg, 219 int hpo_se_inst) 220 { 221 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 222 223 /* set refclk as the source for symclk32_se */ 224 switch (hpo_se_inst) { 225 case 0: 226 REG_UPDATE_2(SYMCLK32_SE_CNTL, 227 SYMCLK32_SE0_SRC_SEL, 0, 228 SYMCLK32_SE0_EN, 0); 229 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 230 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 231 SYMCLK32_SE0_GATE_DISABLE, 0, 232 SYMCLK32_ROOT_SE0_GATE_DISABLE, 0); 233 break; 234 case 1: 235 REG_UPDATE_2(SYMCLK32_SE_CNTL, 236 SYMCLK32_SE1_SRC_SEL, 0, 237 SYMCLK32_SE1_EN, 0); 238 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 239 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 240 SYMCLK32_SE1_GATE_DISABLE, 0, 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_2(DCCG_GATE_DISABLE_CNTL3, 249 SYMCLK32_SE2_GATE_DISABLE, 0, 250 SYMCLK32_ROOT_SE2_GATE_DISABLE, 0); 251 break; 252 case 3: 253 REG_UPDATE_2(SYMCLK32_SE_CNTL, 254 SYMCLK32_SE3_SRC_SEL, 0, 255 SYMCLK32_SE3_EN, 0); 256 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) 257 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 258 SYMCLK32_SE3_GATE_DISABLE, 0, 259 SYMCLK32_ROOT_SE3_GATE_DISABLE, 0); 260 break; 261 default: 262 BREAK_TO_DEBUGGER(); 263 return; 264 } 265 } 266 267 void dccg31_enable_symclk32_le( 268 struct dccg *dccg, 269 int hpo_le_inst, 270 enum phyd32clk_clock_source phyd32clk) 271 { 272 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 273 274 phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk); 275 276 /* select one of the PHYD32CLKs as the source for symclk32_le */ 277 switch (hpo_le_inst) { 278 case 0: 279 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) 280 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 281 SYMCLK32_LE0_GATE_DISABLE, 1, 282 SYMCLK32_ROOT_LE0_GATE_DISABLE, 1); 283 REG_UPDATE_2(SYMCLK32_LE_CNTL, 284 SYMCLK32_LE0_SRC_SEL, phyd32clk, 285 SYMCLK32_LE0_EN, 1); 286 break; 287 case 1: 288 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) 289 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 290 SYMCLK32_LE1_GATE_DISABLE, 1, 291 SYMCLK32_ROOT_LE1_GATE_DISABLE, 1); 292 REG_UPDATE_2(SYMCLK32_LE_CNTL, 293 SYMCLK32_LE1_SRC_SEL, phyd32clk, 294 SYMCLK32_LE1_EN, 1); 295 break; 296 default: 297 BREAK_TO_DEBUGGER(); 298 return; 299 } 300 } 301 302 void dccg31_disable_symclk32_le( 303 struct dccg *dccg, 304 int hpo_le_inst) 305 { 306 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 307 308 /* set refclk as the source for symclk32_le */ 309 switch (hpo_le_inst) { 310 case 0: 311 REG_UPDATE_2(SYMCLK32_LE_CNTL, 312 SYMCLK32_LE0_SRC_SEL, 0, 313 SYMCLK32_LE0_EN, 0); 314 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) 315 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 316 SYMCLK32_LE0_GATE_DISABLE, 0, 317 SYMCLK32_ROOT_LE0_GATE_DISABLE, 0); 318 break; 319 case 1: 320 REG_UPDATE_2(SYMCLK32_LE_CNTL, 321 SYMCLK32_LE1_SRC_SEL, 0, 322 SYMCLK32_LE1_EN, 0); 323 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) 324 REG_UPDATE_2(DCCG_GATE_DISABLE_CNTL3, 325 SYMCLK32_LE1_GATE_DISABLE, 0, 326 SYMCLK32_ROOT_LE1_GATE_DISABLE, 0); 327 break; 328 default: 329 BREAK_TO_DEBUGGER(); 330 return; 331 } 332 } 333 334 void dccg31_disable_dscclk(struct dccg *dccg, int inst) 335 { 336 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 337 338 if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc) 339 return; 340 //DTO must be enabled to generate a 0 Hz clock output 341 switch (inst) { 342 case 0: 343 REG_UPDATE(DSCCLK_DTO_CTRL, 344 DSCCLK0_DTO_ENABLE, 1); 345 REG_UPDATE_2(DSCCLK0_DTO_PARAM, 346 DSCCLK0_DTO_PHASE, 0, 347 DSCCLK0_DTO_MODULO, 1); 348 break; 349 case 1: 350 REG_UPDATE(DSCCLK_DTO_CTRL, 351 DSCCLK1_DTO_ENABLE, 1); 352 REG_UPDATE_2(DSCCLK1_DTO_PARAM, 353 DSCCLK1_DTO_PHASE, 0, 354 DSCCLK1_DTO_MODULO, 1); 355 break; 356 case 2: 357 REG_UPDATE(DSCCLK_DTO_CTRL, 358 DSCCLK2_DTO_ENABLE, 1); 359 REG_UPDATE_2(DSCCLK2_DTO_PARAM, 360 DSCCLK2_DTO_PHASE, 0, 361 DSCCLK2_DTO_MODULO, 1); 362 break; 363 case 3: 364 if (REG(DSCCLK3_DTO_PARAM)) { 365 REG_UPDATE(DSCCLK_DTO_CTRL, 366 DSCCLK3_DTO_ENABLE, 1); 367 REG_UPDATE_2(DSCCLK3_DTO_PARAM, 368 DSCCLK3_DTO_PHASE, 0, 369 DSCCLK3_DTO_MODULO, 1); 370 } 371 break; 372 default: 373 BREAK_TO_DEBUGGER(); 374 return; 375 } 376 } 377 378 void dccg31_enable_dscclk(struct dccg *dccg, int inst) 379 { 380 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 381 382 if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc) 383 return; 384 //Disable DTO 385 switch (inst) { 386 case 0: 387 REG_UPDATE_2(DSCCLK0_DTO_PARAM, 388 DSCCLK0_DTO_PHASE, 0, 389 DSCCLK0_DTO_MODULO, 0); 390 REG_UPDATE(DSCCLK_DTO_CTRL, 391 DSCCLK0_DTO_ENABLE, 0); 392 break; 393 case 1: 394 REG_UPDATE_2(DSCCLK1_DTO_PARAM, 395 DSCCLK1_DTO_PHASE, 0, 396 DSCCLK1_DTO_MODULO, 0); 397 REG_UPDATE(DSCCLK_DTO_CTRL, 398 DSCCLK1_DTO_ENABLE, 0); 399 break; 400 case 2: 401 REG_UPDATE_2(DSCCLK2_DTO_PARAM, 402 DSCCLK2_DTO_PHASE, 0, 403 DSCCLK2_DTO_MODULO, 0); 404 REG_UPDATE(DSCCLK_DTO_CTRL, 405 DSCCLK2_DTO_ENABLE, 0); 406 break; 407 case 3: 408 if (REG(DSCCLK3_DTO_PARAM)) { 409 REG_UPDATE(DSCCLK_DTO_CTRL, 410 DSCCLK3_DTO_ENABLE, 0); 411 REG_UPDATE_2(DSCCLK3_DTO_PARAM, 412 DSCCLK3_DTO_PHASE, 0, 413 DSCCLK3_DTO_MODULO, 0); 414 } 415 break; 416 default: 417 BREAK_TO_DEBUGGER(); 418 return; 419 } 420 } 421 422 void dccg31_set_physymclk( 423 struct dccg *dccg, 424 int phy_inst, 425 enum physymclk_clock_source clk_src, 426 bool force_enable) 427 { 428 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 429 430 /* Force PHYSYMCLK on and Select phyd32clk as the source of clock which is output to PHY through DCIO */ 431 switch (phy_inst) { 432 case 0: 433 if (force_enable) { 434 REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, 435 PHYASYMCLK_FORCE_EN, 1, 436 PHYASYMCLK_FORCE_SRC_SEL, clk_src); 437 if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) 438 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, 439 PHYASYMCLK_GATE_DISABLE, 1); 440 } else { 441 REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, 442 PHYASYMCLK_FORCE_EN, 0, 443 PHYASYMCLK_FORCE_SRC_SEL, 0); 444 if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) 445 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, 446 PHYASYMCLK_GATE_DISABLE, 0); 447 } 448 break; 449 case 1: 450 if (force_enable) { 451 REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, 452 PHYBSYMCLK_FORCE_EN, 1, 453 PHYBSYMCLK_FORCE_SRC_SEL, clk_src); 454 if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) 455 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, 456 PHYBSYMCLK_GATE_DISABLE, 1); 457 } else { 458 REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, 459 PHYBSYMCLK_FORCE_EN, 0, 460 PHYBSYMCLK_FORCE_SRC_SEL, 0); 461 if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) 462 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, 463 PHYBSYMCLK_GATE_DISABLE, 0); 464 } 465 break; 466 case 2: 467 if (force_enable) { 468 REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, 469 PHYCSYMCLK_FORCE_EN, 1, 470 PHYCSYMCLK_FORCE_SRC_SEL, clk_src); 471 if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) 472 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, 473 PHYCSYMCLK_GATE_DISABLE, 1); 474 } else { 475 REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, 476 PHYCSYMCLK_FORCE_EN, 0, 477 PHYCSYMCLK_FORCE_SRC_SEL, 0); 478 if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) 479 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, 480 PHYCSYMCLK_GATE_DISABLE, 0); 481 } 482 break; 483 case 3: 484 if (force_enable) { 485 REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, 486 PHYDSYMCLK_FORCE_EN, 1, 487 PHYDSYMCLK_FORCE_SRC_SEL, clk_src); 488 if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) 489 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, 490 PHYDSYMCLK_GATE_DISABLE, 1); 491 } else { 492 REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, 493 PHYDSYMCLK_FORCE_EN, 0, 494 PHYDSYMCLK_FORCE_SRC_SEL, 0); 495 if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) 496 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, 497 PHYDSYMCLK_GATE_DISABLE, 0); 498 } 499 break; 500 case 4: 501 if (force_enable) { 502 REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, 503 PHYESYMCLK_FORCE_EN, 1, 504 PHYESYMCLK_FORCE_SRC_SEL, clk_src); 505 if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) 506 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, 507 PHYESYMCLK_GATE_DISABLE, 1); 508 } else { 509 REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, 510 PHYESYMCLK_FORCE_EN, 0, 511 PHYESYMCLK_FORCE_SRC_SEL, 0); 512 if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) 513 REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, 514 PHYESYMCLK_GATE_DISABLE, 0); 515 } 516 break; 517 default: 518 BREAK_TO_DEBUGGER(); 519 return; 520 } 521 } 522 523 /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */ 524 void dccg31_set_dtbclk_dto( 525 struct dccg *dccg, 526 const struct dtbclk_dto_params *params) 527 { 528 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 529 int req_dtbclk_khz = params->pixclk_khz; 530 uint32_t dtbdto_div; 531 532 /* Mode DTBDTO Rate DTBCLK_DTO<x>_DIV Register 533 * ODM 4:1 combine pixel rate/4 2 534 * ODM 2:1 combine pixel rate/2 4 535 * non-DSC 4:2:0 mode pixel rate/2 4 536 * DSC native 4:2:0 pixel rate/2 4 537 * DSC native 4:2:2 pixel rate/2 4 538 * Other modes pixel rate 8 539 */ 540 if (params->num_odm_segments == 4) { 541 dtbdto_div = 2; 542 req_dtbclk_khz = params->pixclk_khz / 4; 543 } else if ((params->num_odm_segments == 2) || 544 (params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) || 545 (params->timing->flags.DSC && params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR422 546 && !params->timing->dsc_cfg.ycbcr422_simple)) { 547 dtbdto_div = 4; 548 req_dtbclk_khz = params->pixclk_khz / 2; 549 } else 550 dtbdto_div = 8; 551 552 if (params->ref_dtbclk_khz && req_dtbclk_khz) { 553 uint32_t modulo, phase; 554 555 // phase / modulo = dtbclk / dtbclk ref 556 modulo = params->ref_dtbclk_khz * 1000; 557 phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + params->ref_dtbclk_khz - 1), 558 params->ref_dtbclk_khz); 559 560 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], 561 DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div); 562 563 REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo); 564 REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase); 565 566 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], 567 DTBCLK_DTO_ENABLE[params->otg_inst], 1); 568 569 REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst], 570 DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1, 571 1, 100); 572 573 /* The recommended programming sequence to enable DTBCLK DTO to generate 574 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should 575 * be set only after DTO is enabled 576 */ 577 REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], 578 PIPE_DTO_SRC_SEL[params->otg_inst], 1); 579 } else { 580 REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[params->otg_inst], 581 DTBCLK_DTO_ENABLE[params->otg_inst], 0, 582 PIPE_DTO_SRC_SEL[params->otg_inst], 0, 583 DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div); 584 585 REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0); 586 REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0); 587 } 588 } 589 590 void dccg31_set_audio_dtbclk_dto( 591 struct dccg *dccg, 592 const struct dtbclk_dto_params *params) 593 { 594 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 595 596 if (params->ref_dtbclk_khz && params->req_audio_dtbclk_khz) { 597 uint32_t modulo, phase; 598 599 // phase / modulo = dtbclk / dtbclk ref 600 modulo = params->ref_dtbclk_khz * 1000; 601 phase = div_u64((((unsigned long long)modulo * params->req_audio_dtbclk_khz) + params->ref_dtbclk_khz - 1), 602 params->ref_dtbclk_khz); 603 604 605 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, modulo); 606 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, phase); 607 608 //REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, 609 // DCCG_AUDIO_DTBCLK_DTO_USE_512FBR_DTO, 1); 610 611 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, 612 DCCG_AUDIO_DTO_SEL, 4); // 04 - DCCG_AUDIO_DTO_SEL_AUDIO_DTO_DTBCLK 613 } else { 614 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, 0); 615 REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, 0); 616 617 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, 618 DCCG_AUDIO_DTO_SEL, 3); // 03 - DCCG_AUDIO_DTO_SEL_NO_AUDIO_DTO 619 } 620 } 621 622 void dccg31_get_dccg_ref_freq(struct dccg *dccg, 623 unsigned int xtalin_freq_inKhz, 624 unsigned int *dccg_ref_freq_inKhz) 625 { 626 /* 627 * Assume refclk is sourced from xtalin 628 * expect 24MHz 629 */ 630 *dccg_ref_freq_inKhz = xtalin_freq_inKhz; 631 return; 632 } 633 634 void dccg31_set_dispclk_change_mode( 635 struct dccg *dccg, 636 enum dentist_dispclk_change_mode change_mode) 637 { 638 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 639 640 REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE, 641 change_mode == DISPCLK_CHANGE_MODE_RAMPING ? 2 : 0); 642 } 643 644 void dccg31_init(struct dccg *dccg) 645 { 646 /* Set HPO stream encoder to use refclk to avoid case where PHY is 647 * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which 648 * will cause DCN to hang. 649 */ 650 dccg31_disable_symclk32_se(dccg, 0); 651 dccg31_disable_symclk32_se(dccg, 1); 652 dccg31_disable_symclk32_se(dccg, 2); 653 dccg31_disable_symclk32_se(dccg, 3); 654 655 if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) { 656 dccg31_disable_symclk32_le(dccg, 0); 657 dccg31_disable_symclk32_le(dccg, 1); 658 } 659 660 if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) { 661 dccg31_disable_dpstreamclk(dccg, 0); 662 dccg31_disable_dpstreamclk(dccg, 1); 663 dccg31_disable_dpstreamclk(dccg, 2); 664 dccg31_disable_dpstreamclk(dccg, 3); 665 } 666 667 if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) { 668 dccg31_set_physymclk(dccg, 0, PHYSYMCLK_FORCE_SRC_SYMCLK, false); 669 dccg31_set_physymclk(dccg, 1, PHYSYMCLK_FORCE_SRC_SYMCLK, false); 670 dccg31_set_physymclk(dccg, 2, PHYSYMCLK_FORCE_SRC_SYMCLK, false); 671 dccg31_set_physymclk(dccg, 3, PHYSYMCLK_FORCE_SRC_SYMCLK, false); 672 dccg31_set_physymclk(dccg, 4, PHYSYMCLK_FORCE_SRC_SYMCLK, false); 673 } 674 } 675 676 void dccg31_otg_add_pixel(struct dccg *dccg, 677 uint32_t otg_inst) 678 { 679 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 680 681 REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst], 682 OTG_ADD_PIXEL[otg_inst], 1); 683 } 684 685 void dccg31_otg_drop_pixel(struct dccg *dccg, 686 uint32_t otg_inst) 687 { 688 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 689 690 REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst], 691 OTG_DROP_PIXEL[otg_inst], 1); 692 } 693 694 static const struct dccg_funcs dccg31_funcs = { 695 .update_dpp_dto = dccg31_update_dpp_dto, 696 .get_dccg_ref_freq = dccg31_get_dccg_ref_freq, 697 .dccg_init = dccg31_init, 698 .set_dpstreamclk = dccg31_set_dpstreamclk, 699 .enable_symclk32_se = dccg31_enable_symclk32_se, 700 .disable_symclk32_se = dccg31_disable_symclk32_se, 701 .enable_symclk32_le = dccg31_enable_symclk32_le, 702 .disable_symclk32_le = dccg31_disable_symclk32_le, 703 .set_physymclk = dccg31_set_physymclk, 704 .set_dtbclk_dto = dccg31_set_dtbclk_dto, 705 .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto, 706 .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, 707 .otg_add_pixel = dccg31_otg_add_pixel, 708 .otg_drop_pixel = dccg31_otg_drop_pixel, 709 .set_dispclk_change_mode = dccg31_set_dispclk_change_mode, 710 .disable_dsc = dccg31_disable_dscclk, 711 .enable_dsc = dccg31_enable_dscclk, 712 }; 713 714 struct dccg *dccg31_create( 715 struct dc_context *ctx, 716 const struct dccg_registers *regs, 717 const struct dccg_shift *dccg_shift, 718 const struct dccg_mask *dccg_mask) 719 { 720 struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); 721 struct dccg *base; 722 723 if (dccg_dcn == NULL) { 724 BREAK_TO_DEBUGGER(); 725 return NULL; 726 } 727 728 base = &dccg_dcn->base; 729 base->ctx = ctx; 730 base->funcs = &dccg31_funcs; 731 732 dccg_dcn->regs = regs; 733 dccg_dcn->dccg_shift = dccg_shift; 734 dccg_dcn->dccg_mask = dccg_mask; 735 736 return &dccg_dcn->base; 737 } 738