Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amd/display: Correct sequences and delays for DCN35 PG & RCG

[why]
The current PG & RCG programming in driver has some gaps and incorrect
sequences.

[how]
Added delays after ungating clocks to allow ramp up, increased polling
to allow more time for power up, and removed the incorrect sequences.

Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Signed-off-by: Ovidiu Bunea <ovidiu.bunea@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Ovidiu Bunea and committed by
Alex Deucher
1bde5584 3b14fe98

+111 -164
+1
drivers/gpu/drm/amd/display/dc/dc.h
··· 1162 1162 unsigned int auxless_alpm_lfps_silence_ns; 1163 1163 unsigned int auxless_alpm_lfps_t1t2_us; 1164 1164 short auxless_alpm_lfps_t1t2_offset_us; 1165 + bool enable_pg_cntl_debug_logs; 1165 1166 }; 1166 1167 1167 1168
+39 -35
drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
··· 133 133 }; 134 134 135 135 136 - static void dccg35_set_dsc_clk_rcg(struct dccg *dccg, int inst, bool enable) 136 + static void dccg35_set_dsc_clk_rcg(struct dccg *dccg, int inst, bool allow_rcg) 137 137 { 138 138 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 139 139 140 - if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc && enable) 140 + if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc && allow_rcg) 141 141 return; 142 142 143 143 switch (inst) { 144 144 case 0: 145 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, enable ? 0 : 1); 145 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1); 146 146 break; 147 147 case 1: 148 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, enable ? 0 : 1); 148 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1); 149 149 break; 150 150 case 2: 151 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, enable ? 0 : 1); 151 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1); 152 152 break; 153 153 case 3: 154 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, enable ? 0 : 1); 154 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1); 155 155 break; 156 156 default: 157 157 BREAK_TO_DEBUGGER(); 158 158 return; 159 159 } 160 + 161 + /* Wait for clock to ramp */ 162 + if (!allow_rcg) 163 + udelay(10); 160 164 } 161 165 162 166 static void dccg35_set_symclk32_se_rcg( ··· 389 385 } 390 386 } 391 387 392 - static void dccg35_set_dppclk_rcg(struct dccg *dccg, 393 - int inst, bool enable) 388 + static void dccg35_set_dppclk_rcg(struct dccg *dccg, int inst, bool allow_rcg) 394 389 { 395 - 396 390 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 397 391 398 - 399 - if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable) 392 + if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && allow_rcg) 400 393 return; 401 394 402 395 switch (inst) { 403 396 case 0: 404 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, enable ? 0 : 1); 397 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1); 405 398 break; 406 399 case 1: 407 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, enable ? 0 : 1); 400 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1); 408 401 break; 409 402 case 2: 410 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, enable ? 0 : 1); 403 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1); 411 404 break; 412 405 case 3: 413 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, enable ? 0 : 1); 406 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, allow_rcg ? 0 : 1); 414 407 break; 415 408 default: 416 409 BREAK_TO_DEBUGGER(); 417 410 break; 418 411 } 419 - //DC_LOG_DEBUG("%s: inst(%d) DPPCLK rcg_disable: %d\n", __func__, inst, enable ? 0 : 1); 420 412 413 + /* Wait for clock to ramp */ 414 + if (!allow_rcg) 415 + udelay(10); 421 416 } 422 417 423 418 static void dccg35_set_dpstreamclk_rcg( ··· 1180 1177 } 1181 1178 1182 1179 static void dccg35_set_dppclk_root_clock_gating(struct dccg *dccg, 1183 - uint32_t dpp_inst, uint32_t enable) 1180 + uint32_t dpp_inst, uint32_t disallow_rcg) 1184 1181 { 1185 1182 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 1186 1183 1187 - if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) 1184 + if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && !disallow_rcg) 1188 1185 return; 1189 1186 1190 1187 1191 1188 switch (dpp_inst) { 1192 1189 case 0: 1193 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, enable); 1190 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, disallow_rcg); 1194 1191 break; 1195 1192 case 1: 1196 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, enable); 1193 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, disallow_rcg); 1197 1194 break; 1198 1195 case 2: 1199 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, enable); 1196 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, disallow_rcg); 1200 1197 break; 1201 1198 case 3: 1202 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, enable); 1199 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, disallow_rcg); 1203 1200 break; 1204 1201 default: 1205 1202 break; 1206 1203 } 1207 - //DC_LOG_DEBUG("%s: dpp_inst(%d) rcg: %d\n", __func__, dpp_inst, enable); 1208 1204 1205 + /* Wait for clock to ramp */ 1206 + if (disallow_rcg) 1207 + udelay(10); 1209 1208 } 1210 1209 1211 1210 static void dccg35_get_pixel_rate_div( ··· 1787 1782 //Disable DTO 1788 1783 switch (inst) { 1789 1784 case 0: 1790 - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc) 1791 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, 1); 1785 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK0_ROOT_GATE_DISABLE, 1); 1792 1786 1793 1787 REG_UPDATE_2(DSCCLK0_DTO_PARAM, 1794 1788 DSCCLK0_DTO_PHASE, 0, ··· 1795 1791 REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK0_EN, 1); 1796 1792 break; 1797 1793 case 1: 1798 - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc) 1799 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, 1); 1794 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK1_ROOT_GATE_DISABLE, 1); 1800 1795 1801 1796 REG_UPDATE_2(DSCCLK1_DTO_PARAM, 1802 1797 DSCCLK1_DTO_PHASE, 0, ··· 1803 1800 REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK1_EN, 1); 1804 1801 break; 1805 1802 case 2: 1806 - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc) 1807 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, 1); 1803 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK2_ROOT_GATE_DISABLE, 1); 1808 1804 1809 1805 REG_UPDATE_2(DSCCLK2_DTO_PARAM, 1810 1806 DSCCLK2_DTO_PHASE, 0, ··· 1811 1809 REG_UPDATE(DSCCLK_DTO_CTRL, DSCCLK2_EN, 1); 1812 1810 break; 1813 1811 case 3: 1814 - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dsc) 1815 - REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, 1); 1812 + REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DSCCLK3_ROOT_GATE_DISABLE, 1); 1816 1813 1817 1814 REG_UPDATE_2(DSCCLK3_DTO_PARAM, 1818 1815 DSCCLK3_DTO_PHASE, 0, ··· 1822 1821 BREAK_TO_DEBUGGER(); 1823 1822 return; 1824 1823 } 1824 + 1825 + /* Wait for clock to ramp */ 1826 + udelay(10); 1825 1827 } 1826 1828 1827 1829 static void dccg35_disable_dscclk(struct dccg *dccg, ··· 1868 1864 default: 1869 1865 return; 1870 1866 } 1867 + 1868 + /* Wait for clock ramp */ 1869 + udelay(10); 1871 1870 } 1872 1871 1873 1872 static void dccg35_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst) ··· 2356 2349 2357 2350 void dccg35_root_gate_disable_control(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating) 2358 2351 { 2359 - 2360 - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) { 2361 - dccg35_set_dppclk_root_clock_gating(dccg, pipe_idx, disable_clock_gating); 2362 - } 2352 + dccg35_set_dppclk_root_clock_gating(dccg, pipe_idx, disable_clock_gating); 2363 2353 } 2364 2354 2365 2355 static const struct dccg_funcs dccg35_funcs_new = {
+20 -95
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
··· 113 113 } 114 114 #endif 115 115 116 + static void print_pg_status(struct dc *dc, const char *debug_func, const char *debug_log) 117 + { 118 + if (dc->debug.enable_pg_cntl_debug_logs && dc->res_pool->pg_cntl) { 119 + if (dc->res_pool->pg_cntl->funcs->print_pg_status) 120 + dc->res_pool->pg_cntl->funcs->print_pg_status(dc->res_pool->pg_cntl, debug_func, debug_log); 121 + } 122 + } 123 + 116 124 void dcn35_set_dmu_fgcg(struct dce_hwseq *hws, bool enable) 117 125 { 118 126 REG_UPDATE_3(DMU_CLK_CNTL, ··· 144 136 uint32_t backlight = MAX_BACKLIGHT_LEVEL; 145 137 uint32_t user_level = MAX_BACKLIGHT_LEVEL; 146 138 int i; 139 + 140 + print_pg_status(dc, __func__, ": start"); 147 141 148 142 if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) 149 143 dc->clk_mgr->funcs->init_clocks(dc->clk_mgr); ··· 210 200 211 201 /* we want to turn off all dp displays before doing detection */ 212 202 dc->link_srv->blank_all_dp_displays(dc); 213 - /* 214 - if (hws->funcs.enable_power_gating_plane) 215 - hws->funcs.enable_power_gating_plane(dc->hwseq, true); 216 - */ 203 + 217 204 if (res_pool->hubbub && res_pool->hubbub->funcs->dchubbub_init) 218 205 res_pool->hubbub->funcs->dchubbub_init(dc->res_pool->hubbub); 219 206 /* If taking control over from VBIOS, we may want to optimize our first ··· 243 236 } 244 237 245 238 hws->funcs.init_pipes(dc, dc->current_state); 239 + print_pg_status(dc, __func__, ": after init_pipes"); 240 + 246 241 if (dc->res_pool->hubbub->funcs->allow_self_refresh_control && 247 242 !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter) 248 243 dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, ··· 321 312 if (dc->res_pool->pg_cntl->funcs->init_pg_status) 322 313 dc->res_pool->pg_cntl->funcs->init_pg_status(dc->res_pool->pg_cntl); 323 314 } 315 + print_pg_status(dc, __func__, ": after init_pg_status"); 324 316 } 325 317 326 318 static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) ··· 508 498 hws->ctx->dc->res_pool->dccg->funcs->set_physymclk_root_clock_gating( 509 499 hws->ctx->dc->res_pool->dccg, phy_inst, clock_on); 510 500 } 511 - } 512 - 513 - void dcn35_dsc_pg_control( 514 - struct dce_hwseq *hws, 515 - unsigned int dsc_inst, 516 - bool power_on) 517 - { 518 - uint32_t power_gate = power_on ? 0 : 1; 519 - uint32_t pwr_status = power_on ? 0 : 2; 520 - uint32_t org_ip_request_cntl = 0; 521 - 522 - if (hws->ctx->dc->debug.disable_dsc_power_gate) 523 - return; 524 - if (hws->ctx->dc->debug.ignore_pg) 525 - return; 526 - REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); 527 - if (org_ip_request_cntl == 0) 528 - REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); 529 - 530 - switch (dsc_inst) { 531 - case 0: /* DSC0 */ 532 - REG_UPDATE(DOMAIN16_PG_CONFIG, 533 - DOMAIN_POWER_GATE, power_gate); 534 - 535 - REG_WAIT(DOMAIN16_PG_STATUS, 536 - DOMAIN_PGFSM_PWR_STATUS, pwr_status, 537 - 1, 1000); 538 - break; 539 - case 1: /* DSC1 */ 540 - REG_UPDATE(DOMAIN17_PG_CONFIG, 541 - DOMAIN_POWER_GATE, power_gate); 542 - 543 - REG_WAIT(DOMAIN17_PG_STATUS, 544 - DOMAIN_PGFSM_PWR_STATUS, pwr_status, 545 - 1, 1000); 546 - break; 547 - case 2: /* DSC2 */ 548 - REG_UPDATE(DOMAIN18_PG_CONFIG, 549 - DOMAIN_POWER_GATE, power_gate); 550 - 551 - REG_WAIT(DOMAIN18_PG_STATUS, 552 - DOMAIN_PGFSM_PWR_STATUS, pwr_status, 553 - 1, 1000); 554 - break; 555 - case 3: /* DSC3 */ 556 - REG_UPDATE(DOMAIN19_PG_CONFIG, 557 - DOMAIN_POWER_GATE, power_gate); 558 - 559 - REG_WAIT(DOMAIN19_PG_STATUS, 560 - DOMAIN_PGFSM_PWR_STATUS, pwr_status, 561 - 1, 1000); 562 - break; 563 - default: 564 - BREAK_TO_DEBUGGER(); 565 - break; 566 - } 567 - 568 - if (org_ip_request_cntl == 0) 569 - REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); 570 - } 571 - 572 - void dcn35_enable_power_gating_plane(struct dce_hwseq *hws, bool enable) 573 - { 574 - bool force_on = true; /* disable power gating */ 575 - uint32_t org_ip_request_cntl = 0; 576 - 577 - if (hws->ctx->dc->debug.disable_hubp_power_gate) 578 - return; 579 - if (hws->ctx->dc->debug.ignore_pg) 580 - return; 581 - REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); 582 - if (org_ip_request_cntl == 0) 583 - REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); 584 - /* DCHUBP0/1/2/3/4/5 */ 585 - REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); 586 - REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); 587 - /* DPP0/1/2/3/4/5 */ 588 - REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); 589 - REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); 590 - 591 - force_on = true; /* disable power gating */ 592 - if (enable && !hws->ctx->dc->debug.disable_dsc_power_gate) 593 - force_on = false; 594 - 595 - /* DCS0/1/2/3/4 */ 596 - REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); 597 - REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); 598 - REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); 599 - REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on); 600 - 601 - 602 501 } 603 502 604 503 /* In headless boot cases, DIG may be turned ··· 1372 1453 } 1373 1454 1374 1455 dcn20_prepare_bandwidth(dc, context); 1456 + 1457 + print_pg_status(dc, __func__, ": after rcg and power up"); 1375 1458 } 1376 1459 1377 1460 void dcn35_optimize_bandwidth( ··· 1381 1460 struct dc_state *context) 1382 1461 { 1383 1462 struct pg_block_update pg_update_state; 1463 + 1464 + print_pg_status(dc, __func__, ": before rcg and power up"); 1384 1465 1385 1466 dcn20_optimize_bandwidth(dc, context); 1386 1467 ··· 1395 1472 if (dc->hwss.root_clock_control) 1396 1473 dc->hwss.root_clock_control(dc, &pg_update_state, false); 1397 1474 } 1475 + 1476 + print_pg_status(dc, __func__, ": after rcg and power up"); 1398 1477 } 1399 1478 1400 1479 void dcn35_set_drr(struct pipe_ctx **pipe_ctx,
-3
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
··· 115 115 .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, 116 116 .update_visual_confirm_color = dcn10_update_visual_confirm_color, 117 117 .apply_idle_power_optimizations = dcn35_apply_idle_power_optimizations, 118 - .update_dsc_pg = dcn32_update_dsc_pg, 119 118 .calc_blocks_to_gate = dcn35_calc_blocks_to_gate, 120 119 .calc_blocks_to_ungate = dcn35_calc_blocks_to_ungate, 121 120 .hw_block_power_up = dcn35_hw_block_power_up, ··· 150 151 .plane_atomic_disable = dcn35_plane_atomic_disable, 151 152 //.plane_atomic_disable = dcn20_plane_atomic_disable,/*todo*/ 152 153 //.hubp_pg_control = dcn35_hubp_pg_control, 153 - .enable_power_gating_plane = dcn35_enable_power_gating_plane, 154 154 .dpp_root_clock_control = dcn35_dpp_root_clock_control, 155 155 .dpstream_root_clock_control = dcn35_dpstream_root_clock_control, 156 156 .physymclk_root_clock_control = dcn35_physymclk_root_clock_control, ··· 164 166 .calculate_dccg_k1_k2_values = dcn32_calculate_dccg_k1_k2_values, 165 167 .resync_fifo_dccg_dio = dcn314_resync_fifo_dccg_dio, 166 168 .is_dp_dig_pixel_rate_div_policy = dcn35_is_dp_dig_pixel_rate_div_policy, 167 - .dsc_pg_control = dcn35_dsc_pg_control, 168 169 .dsc_pg_status = dcn32_dsc_pg_status, 169 170 .enable_plane = dcn35_enable_plane, 170 171 .wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
-3
drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
··· 114 114 .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, 115 115 .update_visual_confirm_color = dcn10_update_visual_confirm_color, 116 116 .apply_idle_power_optimizations = dcn35_apply_idle_power_optimizations, 117 - .update_dsc_pg = dcn32_update_dsc_pg, 118 117 .calc_blocks_to_gate = dcn351_calc_blocks_to_gate, 119 118 .calc_blocks_to_ungate = dcn351_calc_blocks_to_ungate, 120 119 .hw_block_power_up = dcn351_hw_block_power_up, ··· 145 146 .plane_atomic_disable = dcn35_plane_atomic_disable, 146 147 //.plane_atomic_disable = dcn20_plane_atomic_disable,/*todo*/ 147 148 //.hubp_pg_control = dcn35_hubp_pg_control, 148 - .enable_power_gating_plane = dcn35_enable_power_gating_plane, 149 149 .dpp_root_clock_control = dcn35_dpp_root_clock_control, 150 150 .dpstream_root_clock_control = dcn35_dpstream_root_clock_control, 151 151 .physymclk_root_clock_control = dcn35_physymclk_root_clock_control, ··· 158 160 .setup_hpo_hw_control = dcn35_setup_hpo_hw_control, 159 161 .calculate_dccg_k1_k2_values = dcn32_calculate_dccg_k1_k2_values, 160 162 .is_dp_dig_pixel_rate_div_policy = dcn35_is_dp_dig_pixel_rate_div_policy, 161 - .dsc_pg_control = dcn35_dsc_pg_control, 162 163 .dsc_pg_status = dcn32_dsc_pg_status, 163 164 .enable_plane = dcn35_enable_plane, 164 165 .wait_for_pipe_update_if_needed = dcn10_wait_for_pipe_update_if_needed,
+1
drivers/gpu/drm/amd/display/dc/inc/hw/pg_cntl.h
··· 49 49 void (*mem_pg_control)(struct pg_cntl *pg_cntl, bool power_on); 50 50 void (*dio_pg_control)(struct pg_cntl *pg_cntl, bool power_on); 51 51 void (*init_pg_status)(struct pg_cntl *pg_cntl); 52 + void (*print_pg_status)(struct pg_cntl *pg_cntl, const char *debug_func, const char *debug_log); 52 53 }; 53 54 54 55 #endif //__DC_PG_CNTL_H__
+50 -28
drivers/gpu/drm/amd/display/dc/pg/dcn35/dcn35_pg_cntl.c
··· 79 79 uint32_t power_gate = power_on ? 0 : 1; 80 80 uint32_t pwr_status = power_on ? 0 : 2; 81 81 uint32_t org_ip_request_cntl = 0; 82 - bool block_enabled; 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; 83 86 84 - /*need to enable dscclk regardless DSC_PG*/ 85 - if (pg_cntl->ctx->dc->res_pool->dccg->funcs->enable_dsc && power_on) 86 - pg_cntl->ctx->dc->res_pool->dccg->funcs->enable_dsc( 87 - pg_cntl->ctx->dc->res_pool->dccg, dsc_inst); 88 - 89 - if (pg_cntl->ctx->dc->debug.ignore_pg || 90 - pg_cntl->ctx->dc->debug.disable_dsc_power_gate || 91 - pg_cntl->ctx->dc->idle_optimizations_allowed) 87 + if (skip_pg && !power_on) 92 88 return; 93 89 94 90 block_enabled = pg_cntl35_dsc_pg_status(pg_cntl, dsc_inst); ··· 107 111 108 112 REG_WAIT(DOMAIN16_PG_STATUS, 109 113 DOMAIN_PGFSM_PWR_STATUS, pwr_status, 110 - 1, 1000); 114 + 1, 10000); 111 115 break; 112 116 case 1: /* DSC1 */ 113 117 REG_UPDATE(DOMAIN17_PG_CONFIG, ··· 115 119 116 120 REG_WAIT(DOMAIN17_PG_STATUS, 117 121 DOMAIN_PGFSM_PWR_STATUS, pwr_status, 118 - 1, 1000); 122 + 1, 10000); 119 123 break; 120 124 case 2: /* DSC2 */ 121 125 REG_UPDATE(DOMAIN18_PG_CONFIG, ··· 123 127 124 128 REG_WAIT(DOMAIN18_PG_STATUS, 125 129 DOMAIN_PGFSM_PWR_STATUS, pwr_status, 126 - 1, 1000); 130 + 1, 10000); 127 131 break; 128 132 case 3: /* DSC3 */ 129 133 REG_UPDATE(DOMAIN19_PG_CONFIG, ··· 131 135 132 136 REG_WAIT(DOMAIN19_PG_STATUS, 133 137 DOMAIN_PGFSM_PWR_STATUS, pwr_status, 134 - 1, 1000); 138 + 1, 10000); 135 139 break; 136 140 default: 137 141 BREAK_TO_DEBUGGER(); ··· 140 144 141 145 if (dsc_inst < MAX_PIPES) 142 146 pg_cntl->pg_pipe_res_enable[PG_DSC][dsc_inst] = power_on; 143 - 144 - if (pg_cntl->ctx->dc->res_pool->dccg->funcs->disable_dsc && !power_on) { 145 - /*this is to disable dscclk*/ 146 - pg_cntl->ctx->dc->res_pool->dccg->funcs->disable_dsc( 147 - pg_cntl->ctx->dc->res_pool->dccg, dsc_inst); 148 - } 149 147 } 150 148 151 149 static bool pg_cntl35_hubp_dpp_pg_status(struct pg_cntl *pg_cntl, unsigned int hubp_dpp_inst) ··· 179 189 uint32_t pwr_status = power_on ? 0 : 2; 180 190 uint32_t org_ip_request_cntl; 181 191 bool block_enabled; 192 + bool skip_pg = pg_cntl->ctx->dc->debug.ignore_pg || 193 + pg_cntl->ctx->dc->debug.disable_hubp_power_gate || 194 + pg_cntl->ctx->dc->debug.disable_dpp_power_gate || 195 + pg_cntl->ctx->dc->idle_optimizations_allowed; 182 196 183 - if (pg_cntl->ctx->dc->debug.ignore_pg || 184 - pg_cntl->ctx->dc->debug.disable_hubp_power_gate || 185 - pg_cntl->ctx->dc->debug.disable_dpp_power_gate || 186 - pg_cntl->ctx->dc->idle_optimizations_allowed) 197 + if (skip_pg && !power_on) 187 198 return; 188 199 189 200 block_enabled = pg_cntl35_hubp_dpp_pg_status(pg_cntl, hubp_dpp_inst); ··· 204 213 case 0: 205 214 /* DPP0 & HUBP0 */ 206 215 REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_GATE, power_gate); 207 - REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000); 216 + REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 10000); 208 217 break; 209 218 case 1: 210 219 /* DPP1 & HUBP1 */ 211 220 REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_GATE, power_gate); 212 - REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000); 221 + REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 10000); 213 222 break; 214 223 case 2: 215 224 /* DPP2 & HUBP2 */ 216 225 REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_GATE, power_gate); 217 - REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000); 226 + REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 10000); 218 227 break; 219 228 case 3: 220 229 /* DPP3 & HUBP3 */ 221 230 REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_GATE, power_gate); 222 - REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000); 231 + REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 10000); 223 232 break; 224 233 default: 225 234 BREAK_TO_DEBUGGER(); ··· 492 501 pg_cntl->pg_res_enable[PG_DWB] = block_enabled; 493 502 } 494 503 504 + static void pg_cntl35_print_pg_status(struct pg_cntl *pg_cntl, const char *debug_func, const char *debug_log) 505 + { 506 + int i = 0; 507 + bool block_enabled = false; 508 + 509 + DC_LOG_DEBUG("%s: %s", debug_func, debug_log); 510 + 511 + DC_LOG_DEBUG("PG_CNTL status:\n"); 512 + 513 + block_enabled = pg_cntl35_io_clk_status(pg_cntl); 514 + DC_LOG_DEBUG("ONO0=%d (DCCG, DIO, DCIO)\n", block_enabled ? 1 : 0); 515 + 516 + block_enabled = pg_cntl35_mem_status(pg_cntl); 517 + DC_LOG_DEBUG("ONO1=%d (DCHUBBUB, DCHVM, DCHUBBUBMEM)\n", block_enabled ? 1 : 0); 518 + 519 + block_enabled = pg_cntl35_plane_otg_status(pg_cntl); 520 + DC_LOG_DEBUG("ONO2=%d (MPC, OPP, OPTC, DWB)\n", block_enabled ? 1 : 0); 521 + 522 + block_enabled = pg_cntl35_hpo_pg_status(pg_cntl); 523 + DC_LOG_DEBUG("ONO3=%d (HPO)\n", block_enabled ? 1 : 0); 524 + 525 + for (i = 0; i < pg_cntl->ctx->dc->res_pool->pipe_count; i++) { 526 + block_enabled = pg_cntl35_hubp_dpp_pg_status(pg_cntl, i); 527 + DC_LOG_DEBUG("ONO%d=%d (DCHUBP%d, DPP%d)\n", 4 + i * 2, block_enabled ? 1 : 0, i, i); 528 + 529 + block_enabled = pg_cntl35_dsc_pg_status(pg_cntl, i); 530 + DC_LOG_DEBUG("ONO%d=%d (DSC%d)\n", 5 + i * 2, block_enabled ? 1 : 0, i); 531 + } 532 + } 533 + 495 534 static const struct pg_cntl_funcs pg_cntl35_funcs = { 496 535 .init_pg_status = pg_cntl35_init_pg_status, 497 536 .dsc_pg_control = pg_cntl35_dsc_pg_control, ··· 532 511 .mpcc_pg_control = pg_cntl35_mpcc_pg_control, 533 512 .opp_pg_control = pg_cntl35_opp_pg_control, 534 513 .optc_pg_control = pg_cntl35_optc_pg_control, 535 - .dwb_pg_control = pg_cntl35_dwb_pg_control 514 + .dwb_pg_control = pg_cntl35_dwb_pg_control, 515 + .print_pg_status = pg_cntl35_print_pg_status 536 516 }; 537 517 538 518 struct pg_cntl *pg_cntl35_create(