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 * Authors: AMD 24 * 25 */ 26 27 #include "reg_helper.h" 28 #include "core_types.h" 29 #include "dcn35_pg_cntl.h" 30 #include "dccg.h" 31 32 #define TO_DCN_PG_CNTL(pg_cntl)\ 33 container_of(pg_cntl, struct dcn_pg_cntl, base) 34 35 #define REG(reg) \ 36 (pg_cntl_dcn->regs->reg) 37 38 #undef FN 39 #define FN(reg_name, field_name) \ 40 pg_cntl_dcn->pg_cntl_shift->field_name, pg_cntl_dcn->pg_cntl_mask->field_name 41 42 #define CTX \ 43 pg_cntl_dcn->base.ctx 44 #define DC_LOGGER \ 45 pg_cntl->ctx->logger 46 47 static bool pg_cntl35_dsc_pg_status(struct pg_cntl *pg_cntl, unsigned int dsc_inst) 48 { 49 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl); 50 uint32_t pwr_status = 0; 51 52 if (pg_cntl->ctx->dc->debug.ignore_pg) 53 return true; 54 55 switch (dsc_inst) { 56 case 0: /* DSC0 */ 57 REG_GET(DOMAIN16_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 58 break; 59 case 1: /* DSC1 */ 60 REG_GET(DOMAIN17_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 61 break; 62 case 2: /* DSC2 */ 63 REG_GET(DOMAIN18_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 64 break; 65 case 3: /* DSC3 */ 66 REG_GET(DOMAIN19_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 67 break; 68 default: 69 BREAK_TO_DEBUGGER(); 70 break; 71 } 72 73 return pwr_status == 0; 74 } 75 76 void pg_cntl35_dsc_pg_control(struct pg_cntl *pg_cntl, unsigned int dsc_inst, bool power_on) 77 { 78 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl); 79 uint32_t power_gate = power_on ? 0 : 1; 80 uint32_t pwr_status = power_on ? 0 : 2; 81 uint32_t org_ip_request_cntl = 0; 82 bool block_enabled = false; 83 bool skip_pg = pg_cntl->ctx->dc->debug.ignore_pg || 84 pg_cntl->ctx->dc->debug.disable_dsc_power_gate || 85 pg_cntl->ctx->dc->idle_optimizations_allowed; 86 87 if (skip_pg && !power_on) 88 return; 89 90 block_enabled = pg_cntl35_dsc_pg_status(pg_cntl, dsc_inst); 91 if (power_on) { 92 if (block_enabled) 93 return; 94 } else { 95 if (!block_enabled) 96 return; 97 } 98 99 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); 100 if (org_ip_request_cntl == 0) 101 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); 102 103 switch (dsc_inst) { 104 case 0: /* DSC0 */ 105 REG_UPDATE(DOMAIN16_PG_CONFIG, 106 DOMAIN_POWER_GATE, power_gate); 107 108 REG_WAIT(DOMAIN16_PG_STATUS, 109 DOMAIN_PGFSM_PWR_STATUS, pwr_status, 110 1, 10000); 111 break; 112 case 1: /* DSC1 */ 113 REG_UPDATE(DOMAIN17_PG_CONFIG, 114 DOMAIN_POWER_GATE, power_gate); 115 116 REG_WAIT(DOMAIN17_PG_STATUS, 117 DOMAIN_PGFSM_PWR_STATUS, pwr_status, 118 1, 10000); 119 break; 120 case 2: /* DSC2 */ 121 REG_UPDATE(DOMAIN18_PG_CONFIG, 122 DOMAIN_POWER_GATE, power_gate); 123 124 REG_WAIT(DOMAIN18_PG_STATUS, 125 DOMAIN_PGFSM_PWR_STATUS, pwr_status, 126 1, 10000); 127 break; 128 case 3: /* DSC3 */ 129 REG_UPDATE(DOMAIN19_PG_CONFIG, 130 DOMAIN_POWER_GATE, power_gate); 131 132 REG_WAIT(DOMAIN19_PG_STATUS, 133 DOMAIN_PGFSM_PWR_STATUS, pwr_status, 134 1, 10000); 135 break; 136 default: 137 BREAK_TO_DEBUGGER(); 138 break; 139 } 140 141 if (dsc_inst < MAX_PIPES) 142 pg_cntl->pg_pipe_res_enable[PG_DSC][dsc_inst] = power_on; 143 } 144 145 static bool pg_cntl35_hubp_dpp_pg_status(struct pg_cntl *pg_cntl, unsigned int hubp_dpp_inst) 146 { 147 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl); 148 uint32_t pwr_status = 0; 149 150 switch (hubp_dpp_inst) { 151 case 0: 152 /* DPP0 & HUBP0 */ 153 REG_GET(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 154 break; 155 case 1: 156 /* DPP1 & HUBP1 */ 157 REG_GET(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 158 break; 159 case 2: 160 /* DPP2 & HUBP2 */ 161 REG_GET(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 162 break; 163 case 3: 164 /* DPP3 & HUBP3 */ 165 REG_GET(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 166 break; 167 default: 168 BREAK_TO_DEBUGGER(); 169 break; 170 } 171 172 return pwr_status == 0; 173 } 174 175 void pg_cntl35_hubp_dpp_pg_control(struct pg_cntl *pg_cntl, unsigned int hubp_dpp_inst, bool power_on) 176 { 177 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl); 178 uint32_t power_gate = power_on ? 0 : 1; 179 uint32_t pwr_status = power_on ? 0 : 2; 180 uint32_t org_ip_request_cntl; 181 bool block_enabled; 182 bool skip_pg = pg_cntl->ctx->dc->debug.ignore_pg || 183 pg_cntl->ctx->dc->debug.disable_hubp_power_gate || 184 pg_cntl->ctx->dc->debug.disable_dpp_power_gate || 185 pg_cntl->ctx->dc->idle_optimizations_allowed; 186 187 if (skip_pg && !power_on) 188 return; 189 190 block_enabled = pg_cntl35_hubp_dpp_pg_status(pg_cntl, hubp_dpp_inst); 191 if (power_on) { 192 if (block_enabled) 193 return; 194 } else { 195 if (!block_enabled) 196 return; 197 } 198 199 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); 200 if (org_ip_request_cntl == 0) 201 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); 202 203 switch (hubp_dpp_inst) { 204 case 0: 205 /* DPP0 & HUBP0 */ 206 REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, power_gate); 207 REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 10000); 208 break; 209 case 1: 210 /* DPP1 & HUBP1 */ 211 REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_GATE, power_gate); 212 REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 10000); 213 break; 214 case 2: 215 /* DPP2 & HUBP2 */ 216 REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_GATE, power_gate); 217 REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 10000); 218 break; 219 case 3: 220 /* DPP3 & HUBP3 */ 221 REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_GATE, power_gate); 222 REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 10000); 223 break; 224 default: 225 BREAK_TO_DEBUGGER(); 226 break; 227 } 228 229 DC_LOG_DEBUG("HUBP DPP instance %d, power %s", hubp_dpp_inst, 230 power_on ? "ON" : "OFF"); 231 232 if (hubp_dpp_inst < MAX_PIPES) { 233 pg_cntl->pg_pipe_res_enable[PG_HUBP][hubp_dpp_inst] = power_on; 234 pg_cntl->pg_pipe_res_enable[PG_DPP][hubp_dpp_inst] = power_on; 235 } 236 } 237 238 static bool pg_cntl35_hpo_pg_status(struct pg_cntl *pg_cntl) 239 { 240 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl); 241 uint32_t pwr_status = 0; 242 243 REG_GET(DOMAIN25_PG_STATUS, 244 DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 245 246 return pwr_status == 0; 247 } 248 249 void pg_cntl35_hpo_pg_control(struct pg_cntl *pg_cntl, bool power_on) 250 { 251 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl); 252 uint32_t power_gate = power_on ? 0 : 1; 253 uint32_t pwr_status = power_on ? 0 : 2; 254 uint32_t org_ip_request_cntl; 255 uint32_t power_forceon; 256 bool block_enabled; 257 258 if (pg_cntl->ctx->dc->debug.ignore_pg || 259 pg_cntl->ctx->dc->debug.disable_hpo_power_gate || 260 pg_cntl->ctx->dc->idle_optimizations_allowed) 261 return; 262 263 block_enabled = pg_cntl35_hpo_pg_status(pg_cntl); 264 if (power_on) { 265 if (block_enabled) 266 return; 267 } else { 268 if (!block_enabled) 269 return; 270 } 271 272 REG_GET(DOMAIN25_PG_CONFIG, DOMAIN_POWER_FORCEON, &power_forceon); 273 if (power_forceon) 274 return; 275 276 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); 277 if (org_ip_request_cntl == 0) 278 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); 279 280 REG_UPDATE(DOMAIN25_PG_CONFIG, DOMAIN_POWER_GATE, power_gate); 281 REG_WAIT(DOMAIN25_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000); 282 283 pg_cntl->pg_res_enable[PG_HPO] = power_on; 284 } 285 286 static bool pg_cntl35_io_clk_status(struct pg_cntl *pg_cntl) 287 { 288 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl); 289 uint32_t pwr_status = 0; 290 291 REG_GET(DOMAIN22_PG_STATUS, 292 DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 293 294 return pwr_status == 0; 295 } 296 297 void pg_cntl35_io_clk_pg_control(struct pg_cntl *pg_cntl, bool power_on) 298 { 299 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl); 300 uint32_t power_gate = power_on ? 0 : 1; 301 uint32_t pwr_status = power_on ? 0 : 2; 302 uint32_t org_ip_request_cntl; 303 uint32_t power_forceon; 304 bool block_enabled; 305 306 if (pg_cntl->ctx->dc->debug.ignore_pg || 307 pg_cntl->ctx->dc->idle_optimizations_allowed) 308 return; 309 310 block_enabled = pg_cntl35_io_clk_status(pg_cntl); 311 if (power_on) { 312 if (block_enabled) 313 return; 314 } else { 315 if (!block_enabled) 316 return; 317 } 318 319 REG_GET(DOMAIN22_PG_CONFIG, DOMAIN_POWER_FORCEON, &power_forceon); 320 if (power_forceon) 321 return; 322 323 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); 324 if (org_ip_request_cntl == 0) 325 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); 326 327 /* DCCG, DIO, DCIO */ 328 REG_UPDATE(DOMAIN22_PG_CONFIG, DOMAIN_POWER_GATE, power_gate); 329 REG_WAIT(DOMAIN22_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000); 330 331 pg_cntl->pg_res_enable[PG_DCCG] = power_on; 332 pg_cntl->pg_res_enable[PG_DIO] = power_on; 333 pg_cntl->pg_res_enable[PG_DCIO] = power_on; 334 } 335 336 static bool pg_cntl35_plane_otg_status(struct pg_cntl *pg_cntl) 337 { 338 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl); 339 uint32_t pwr_status = 0; 340 341 REG_GET(DOMAIN24_PG_STATUS, 342 DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 343 344 return pwr_status == 0; 345 } 346 347 void pg_cntl35_mpcc_pg_control(struct pg_cntl *pg_cntl, 348 unsigned int mpcc_inst, bool power_on) 349 { 350 if (pg_cntl->ctx->dc->idle_optimizations_allowed) 351 return; 352 353 if (mpcc_inst < MAX_PIPES) 354 pg_cntl->pg_pipe_res_enable[PG_MPCC][mpcc_inst] = power_on; 355 } 356 357 void pg_cntl35_opp_pg_control(struct pg_cntl *pg_cntl, 358 unsigned int opp_inst, bool power_on) 359 { 360 if (pg_cntl->ctx->dc->idle_optimizations_allowed) 361 return; 362 363 if (opp_inst < MAX_PIPES) 364 pg_cntl->pg_pipe_res_enable[PG_OPP][opp_inst] = power_on; 365 } 366 367 void pg_cntl35_optc_pg_control(struct pg_cntl *pg_cntl, 368 unsigned int optc_inst, bool power_on) 369 { 370 if (pg_cntl->ctx->dc->idle_optimizations_allowed) 371 return; 372 373 if (optc_inst < MAX_PIPES) 374 pg_cntl->pg_pipe_res_enable[PG_OPTC][optc_inst] = power_on; 375 } 376 377 void pg_cntl35_plane_otg_pg_control(struct pg_cntl *pg_cntl, bool power_on) 378 { 379 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl); 380 uint32_t power_gate = power_on ? 0 : 1; 381 uint32_t pwr_status = power_on ? 0 : 2; 382 uint32_t org_ip_request_cntl; 383 unsigned int i; 384 bool block_enabled; 385 bool all_mpcc_disabled = true, all_opp_disabled = true; 386 bool all_optc_disabled = true, all_stream_disabled = true; 387 388 if (pg_cntl->ctx->dc->debug.ignore_pg || 389 pg_cntl->ctx->dc->debug.disable_optc_power_gate || 390 pg_cntl->ctx->dc->idle_optimizations_allowed) 391 return; 392 393 block_enabled = pg_cntl35_plane_otg_status(pg_cntl); 394 if (power_on) { 395 if (block_enabled) 396 return; 397 } else { 398 if (!block_enabled) 399 return; 400 } 401 402 for (i = 0; i < pg_cntl->ctx->dc->res_pool->pipe_count; i++) { 403 struct pipe_ctx *pipe_ctx = &pg_cntl->ctx->dc->current_state->res_ctx.pipe_ctx[i]; 404 405 if (pipe_ctx) { 406 if (pipe_ctx->stream) 407 all_stream_disabled = false; 408 } 409 410 if (pg_cntl->pg_pipe_res_enable[PG_MPCC][i]) 411 all_mpcc_disabled = false; 412 413 if (pg_cntl->pg_pipe_res_enable[PG_OPP][i]) 414 all_opp_disabled = false; 415 416 if (pg_cntl->pg_pipe_res_enable[PG_OPTC][i]) 417 all_optc_disabled = false; 418 } 419 420 if (!power_on) { 421 if (!all_mpcc_disabled || !all_opp_disabled || !all_optc_disabled 422 || !all_stream_disabled || pg_cntl->pg_res_enable[PG_DWB]) 423 return; 424 } 425 426 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); 427 if (org_ip_request_cntl == 0) 428 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); 429 430 /* MPC, OPP, OPTC, DWB */ 431 REG_UPDATE(DOMAIN24_PG_CONFIG, DOMAIN_POWER_GATE, power_gate); 432 REG_WAIT(DOMAIN24_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000); 433 434 for (i = 0; i < pg_cntl->ctx->dc->res_pool->pipe_count; i++) { 435 pg_cntl->pg_pipe_res_enable[PG_MPCC][i] = power_on; 436 pg_cntl->pg_pipe_res_enable[PG_OPP][i] = power_on; 437 pg_cntl->pg_pipe_res_enable[PG_OPTC][i] = power_on; 438 } 439 pg_cntl->pg_res_enable[PG_DWB] = power_on; 440 } 441 442 void pg_cntl35_dwb_pg_control(struct pg_cntl *pg_cntl, bool power_on) 443 { 444 if (pg_cntl->ctx->dc->idle_optimizations_allowed) 445 return; 446 447 pg_cntl->pg_res_enable[PG_DWB] = power_on; 448 } 449 450 static bool pg_cntl35_mem_status(struct pg_cntl *pg_cntl) 451 { 452 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(pg_cntl); 453 uint32_t pwr_status = 0; 454 455 REG_GET(DOMAIN23_PG_STATUS, 456 DOMAIN_PGFSM_PWR_STATUS, &pwr_status); 457 458 return pwr_status == 0; 459 } 460 461 void pg_cntl35_init_pg_status(struct pg_cntl *pg_cntl) 462 { 463 unsigned int i = 0; 464 bool block_enabled; 465 466 pg_cntl->pg_res_enable[PG_HPO] = pg_cntl35_hpo_pg_status(pg_cntl); 467 468 block_enabled = pg_cntl35_io_clk_status(pg_cntl); 469 pg_cntl->pg_res_enable[PG_DCCG] = block_enabled; 470 pg_cntl->pg_res_enable[PG_DIO] = block_enabled; 471 pg_cntl->pg_res_enable[PG_DCIO] = block_enabled; 472 473 block_enabled = pg_cntl35_mem_status(pg_cntl); 474 pg_cntl->pg_res_enable[PG_DCHUBBUB] = block_enabled; 475 pg_cntl->pg_res_enable[PG_DCHVM] = block_enabled; 476 477 for (i = 0; i < pg_cntl->ctx->dc->res_pool->pipe_count; i++) { 478 block_enabled = pg_cntl35_hubp_dpp_pg_status(pg_cntl, i); 479 pg_cntl->pg_pipe_res_enable[PG_HUBP][i] = block_enabled; 480 pg_cntl->pg_pipe_res_enable[PG_DPP][i] = block_enabled; 481 482 block_enabled = pg_cntl35_dsc_pg_status(pg_cntl, i); 483 pg_cntl->pg_pipe_res_enable[PG_DSC][i] = block_enabled; 484 } 485 486 block_enabled = pg_cntl35_plane_otg_status(pg_cntl); 487 for (i = 0; i < pg_cntl->ctx->dc->res_pool->pipe_count; i++) { 488 pg_cntl->pg_pipe_res_enable[PG_MPCC][i] = block_enabled; 489 pg_cntl->pg_pipe_res_enable[PG_OPP][i] = block_enabled; 490 pg_cntl->pg_pipe_res_enable[PG_OPTC][i] = block_enabled; 491 } 492 pg_cntl->pg_res_enable[PG_DWB] = block_enabled; 493 } 494 495 static void pg_cntl35_print_pg_status(struct pg_cntl *pg_cntl, const char *debug_func, const char *debug_log) 496 { 497 unsigned int i = 0; 498 bool block_enabled = false; 499 500 DC_LOG_DEBUG("%s: %s", debug_func, debug_log); 501 502 DC_LOG_DEBUG("PG_CNTL status:\n"); 503 504 block_enabled = pg_cntl35_io_clk_status(pg_cntl); 505 DC_LOG_DEBUG("ONO0=%d (DCCG, DIO, DCIO)\n", block_enabled ? 1 : 0); 506 507 block_enabled = pg_cntl35_mem_status(pg_cntl); 508 DC_LOG_DEBUG("ONO1=%d (DCHUBBUB, DCHVM, DCHUBBUBMEM)\n", block_enabled ? 1 : 0); 509 510 block_enabled = pg_cntl35_plane_otg_status(pg_cntl); 511 DC_LOG_DEBUG("ONO2=%d (MPC, OPP, OPTC, DWB)\n", block_enabled ? 1 : 0); 512 513 block_enabled = pg_cntl35_hpo_pg_status(pg_cntl); 514 DC_LOG_DEBUG("ONO3=%d (HPO)\n", block_enabled ? 1 : 0); 515 516 for (i = 0; i < pg_cntl->ctx->dc->res_pool->pipe_count; i++) { 517 block_enabled = pg_cntl35_hubp_dpp_pg_status(pg_cntl, i); 518 DC_LOG_DEBUG("ONO%d=%d (DCHUBP%d, DPP%d)\n", 4 + i * 2, block_enabled ? 1 : 0, i, i); 519 520 block_enabled = pg_cntl35_dsc_pg_status(pg_cntl, i); 521 DC_LOG_DEBUG("ONO%d=%d (DSC%d)\n", 5 + i * 2, block_enabled ? 1 : 0, i); 522 } 523 } 524 525 static const struct pg_cntl_funcs pg_cntl35_funcs = { 526 .init_pg_status = pg_cntl35_init_pg_status, 527 .dsc_pg_control = pg_cntl35_dsc_pg_control, 528 .hubp_dpp_pg_control = pg_cntl35_hubp_dpp_pg_control, 529 .hpo_pg_control = pg_cntl35_hpo_pg_control, 530 .io_clk_pg_control = pg_cntl35_io_clk_pg_control, 531 .plane_otg_pg_control = pg_cntl35_plane_otg_pg_control, 532 .mpcc_pg_control = pg_cntl35_mpcc_pg_control, 533 .opp_pg_control = pg_cntl35_opp_pg_control, 534 .optc_pg_control = pg_cntl35_optc_pg_control, 535 .dwb_pg_control = pg_cntl35_dwb_pg_control, 536 .print_pg_status = pg_cntl35_print_pg_status 537 }; 538 539 struct pg_cntl *pg_cntl35_create( 540 struct dc_context *ctx, 541 const struct pg_cntl_registers *regs, 542 const struct pg_cntl_shift *pg_cntl_shift, 543 const struct pg_cntl_mask *pg_cntl_mask) 544 { 545 struct dcn_pg_cntl *pg_cntl_dcn = kzalloc_obj(*pg_cntl_dcn); 546 struct pg_cntl *base; 547 548 if (pg_cntl_dcn == NULL) { 549 BREAK_TO_DEBUGGER(); 550 return NULL; 551 } 552 553 base = &pg_cntl_dcn->base; 554 base->ctx = ctx; 555 base->funcs = &pg_cntl35_funcs; 556 557 pg_cntl_dcn->regs = regs; 558 pg_cntl_dcn->pg_cntl_shift = pg_cntl_shift; 559 pg_cntl_dcn->pg_cntl_mask = pg_cntl_mask; 560 561 memset(base->pg_pipe_res_enable, 0, PG_HW_PIPE_RESOURCES_NUM_ELEMENT * MAX_PIPES * sizeof(bool)); 562 memset(base->pg_res_enable, 0, PG_HW_RESOURCES_NUM_ELEMENT * sizeof(bool)); 563 564 return &pg_cntl_dcn->base; 565 } 566 567 void dcn_pg_cntl_destroy(struct pg_cntl **pg_cntl) 568 { 569 struct dcn_pg_cntl *pg_cntl_dcn = TO_DCN_PG_CNTL(*pg_cntl); 570 571 kfree(pg_cntl_dcn); 572 *pg_cntl = NULL; 573 } 574