0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include "dm_services.h"
0028 #include "dm_helpers.h"
0029 #include "core_types.h"
0030 #include "resource.h"
0031 #include "dccg.h"
0032 #include "dce/dce_hwseq.h"
0033 #include "clk_mgr.h"
0034 #include "reg_helper.h"
0035 #include "abm.h"
0036 #include "hubp.h"
0037 #include "dchubbub.h"
0038 #include "timing_generator.h"
0039 #include "opp.h"
0040 #include "ipp.h"
0041 #include "mpc.h"
0042 #include "mcif_wb.h"
0043 #include "dc_dmub_srv.h"
0044 #include "dcn31_hwseq.h"
0045 #include "link_hwss.h"
0046 #include "dpcd_defs.h"
0047 #include "dce/dmub_outbox.h"
0048 #include "dc_link_dp.h"
0049 #include "inc/link_dpcd.h"
0050 #include "dcn10/dcn10_hw_sequencer.h"
0051 #include "inc/link_enc_cfg.h"
0052 #include "dcn30/dcn30_vpg.h"
0053 #include "dce/dce_i2c_hw.h"
0054
0055 #define DC_LOGGER_INIT(logger)
0056
0057 #define CTX \
0058 hws->ctx
0059 #define REG(reg)\
0060 hws->regs->reg
0061 #define DC_LOGGER \
0062 dc->ctx->logger
0063
0064
0065 #undef FN
0066 #define FN(reg_name, field_name) \
0067 hws->shifts->field_name, hws->masks->field_name
0068
0069 static void enable_memory_low_power(struct dc *dc)
0070 {
0071 struct dce_hwseq *hws = dc->hwseq;
0072 int i;
0073
0074 if (dc->debug.enable_mem_low_power.bits.dmcu) {
0075
0076 if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
0077 REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
0078 }
0079 }
0080
0081
0082 if (dc->debug.enable_mem_low_power.bits.optc) {
0083
0084 REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
0085 }
0086
0087 if (dc->debug.enable_mem_low_power.bits.vga) {
0088
0089 REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
0090 }
0091
0092 if (dc->debug.enable_mem_low_power.bits.mpc)
0093 dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode(dc->res_pool->mpc);
0094
0095
0096 if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
0097
0098 for (i = 0; i < dc->res_pool->stream_enc_count; i++)
0099 dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
0100 #if defined(CONFIG_DRM_AMD_DC_DCN)
0101 for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
0102 dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
0103 #endif
0104 }
0105
0106 }
0107
0108 void dcn31_init_hw(struct dc *dc)
0109 {
0110 struct abm **abms = dc->res_pool->multiple_abms;
0111 struct dce_hwseq *hws = dc->hwseq;
0112 struct dc_bios *dcb = dc->ctx->dc_bios;
0113 struct resource_pool *res_pool = dc->res_pool;
0114 uint32_t backlight = MAX_BACKLIGHT_LEVEL;
0115 int i;
0116
0117 if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
0118 dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
0119
0120 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
0121
0122 REG_WRITE(REFCLK_CNTL, 0);
0123 REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
0124 REG_WRITE(DIO_MEM_PWR_CTRL, 0);
0125
0126 if (!dc->debug.disable_clock_gate) {
0127
0128 REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
0129
0130 REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
0131
0132 REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
0133 }
0134
0135
0136 if (hws->funcs.enable_power_gating_plane)
0137 hws->funcs.enable_power_gating_plane(hws, true);
0138
0139 return;
0140 }
0141
0142 if (!dcb->funcs->is_accelerated_mode(dcb)) {
0143 hws->funcs.bios_golden_init(dc);
0144 hws->funcs.disable_vga(dc->hwseq);
0145 }
0146
0147 if (res_pool->dccg->funcs->dccg_init)
0148 res_pool->dccg->funcs->dccg_init(res_pool->dccg);
0149
0150 enable_memory_low_power(dc);
0151
0152 if (dc->ctx->dc_bios->fw_info_valid) {
0153 res_pool->ref_clocks.xtalin_clock_inKhz =
0154 dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
0155
0156 if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
0157 if (res_pool->dccg && res_pool->hubbub) {
0158
0159 (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
0160 dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
0161 &res_pool->ref_clocks.dccg_ref_clock_inKhz);
0162
0163 (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
0164 res_pool->ref_clocks.dccg_ref_clock_inKhz,
0165 &res_pool->ref_clocks.dchub_ref_clock_inKhz);
0166 } else {
0167
0168 res_pool->ref_clocks.dccg_ref_clock_inKhz =
0169 res_pool->ref_clocks.xtalin_clock_inKhz;
0170 res_pool->ref_clocks.dchub_ref_clock_inKhz =
0171 res_pool->ref_clocks.xtalin_clock_inKhz;
0172 }
0173 }
0174 } else
0175 ASSERT_CRITICAL(false);
0176
0177 for (i = 0; i < dc->link_count; i++) {
0178
0179
0180
0181
0182 struct dc_link *link = dc->links[i];
0183
0184 if (link->ep_type != DISPLAY_ENDPOINT_PHY)
0185 continue;
0186
0187 link->link_enc->funcs->hw_init(link->link_enc);
0188
0189
0190 if (link->link_enc->funcs->is_dig_enabled &&
0191 link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
0192 link->link_status.link_active = true;
0193 if (link->link_enc->funcs->fec_is_active &&
0194 link->link_enc->funcs->fec_is_active(link->link_enc))
0195 link->fec_state = dc_link_fec_enabled;
0196 }
0197 }
0198
0199
0200 if (dc->res_pool->usb4_dpia_count)
0201 dmub_enable_outbox_notification(dc->ctx->dmub_srv);
0202
0203
0204 dc_link_blank_all_dp_displays(dc);
0205
0206 if (hws->funcs.enable_power_gating_plane)
0207 hws->funcs.enable_power_gating_plane(dc->hwseq, true);
0208
0209
0210
0211
0212
0213
0214
0215 if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {
0216
0217
0218 if (!dc->caps.seamless_odm) {
0219 for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
0220 struct timing_generator *tg = dc->res_pool->timing_generators[i];
0221 uint32_t num_opps, opp_id_src0, opp_id_src1;
0222
0223 num_opps = 1;
0224 if (tg) {
0225 if (tg->funcs->is_tg_enabled(tg) && tg->funcs->get_optc_source) {
0226 tg->funcs->get_optc_source(tg, &num_opps,
0227 &opp_id_src0, &opp_id_src1);
0228 }
0229 }
0230
0231 if (num_opps > 1) {
0232 dc_link_blank_all_edp_displays(dc);
0233 break;
0234 }
0235 }
0236 }
0237
0238 hws->funcs.init_pipes(dc, dc->current_state);
0239 if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
0240 dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
0241 !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
0242 }
0243
0244 for (i = 0; i < res_pool->audio_count; i++) {
0245 struct audio *audio = res_pool->audios[i];
0246
0247 audio->funcs->hw_init(audio);
0248 }
0249
0250 for (i = 0; i < dc->link_count; i++) {
0251 struct dc_link *link = dc->links[i];
0252
0253 if (link->panel_cntl)
0254 backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
0255 }
0256
0257 for (i = 0; i < dc->res_pool->pipe_count; i++) {
0258 if (abms[i] != NULL)
0259 abms[i]->funcs->abm_init(abms[i], backlight);
0260 }
0261
0262
0263 REG_WRITE(DIO_MEM_PWR_CTRL, 0);
0264
0265
0266 if (dc->debug.enable_mem_low_power.bits.i2c)
0267 REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1);
0268
0269 if (hws->funcs.setup_hpo_hw_control)
0270 hws->funcs.setup_hpo_hw_control(hws, false);
0271
0272 if (!dc->debug.disable_clock_gate) {
0273
0274 REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
0275
0276 REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
0277
0278 REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
0279 }
0280
0281 if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
0282 dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
0283
0284 if (dc->clk_mgr->funcs->notify_wm_ranges)
0285 dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
0286
0287 if (dc->clk_mgr->funcs->set_hard_max_memclk)
0288 dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
0289
0290 if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
0291 dc->res_pool->hubbub->funcs->force_pstate_change_control(
0292 dc->res_pool->hubbub, false, false);
0293 #if defined(CONFIG_DRM_AMD_DC_DCN)
0294 if (dc->res_pool->hubbub->funcs->init_crb)
0295 dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
0296 #endif
0297 }
0298
0299 void dcn31_dsc_pg_control(
0300 struct dce_hwseq *hws,
0301 unsigned int dsc_inst,
0302 bool power_on)
0303 {
0304 uint32_t power_gate = power_on ? 0 : 1;
0305 uint32_t pwr_status = power_on ? 0 : 2;
0306 uint32_t org_ip_request_cntl = 0;
0307
0308 if (hws->ctx->dc->debug.disable_dsc_power_gate)
0309 return;
0310
0311 if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc &&
0312 hws->ctx->dc->res_pool->dccg->funcs->enable_dsc &&
0313 power_on)
0314 hws->ctx->dc->res_pool->dccg->funcs->enable_dsc(
0315 hws->ctx->dc->res_pool->dccg, dsc_inst);
0316
0317 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
0318 if (org_ip_request_cntl == 0)
0319 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
0320
0321 switch (dsc_inst) {
0322 case 0:
0323 REG_UPDATE(DOMAIN16_PG_CONFIG,
0324 DOMAIN_POWER_GATE, power_gate);
0325
0326 REG_WAIT(DOMAIN16_PG_STATUS,
0327 DOMAIN_PGFSM_PWR_STATUS, pwr_status,
0328 1, 1000);
0329 break;
0330 case 1:
0331 REG_UPDATE(DOMAIN17_PG_CONFIG,
0332 DOMAIN_POWER_GATE, power_gate);
0333
0334 REG_WAIT(DOMAIN17_PG_STATUS,
0335 DOMAIN_PGFSM_PWR_STATUS, pwr_status,
0336 1, 1000);
0337 break;
0338 case 2:
0339 REG_UPDATE(DOMAIN18_PG_CONFIG,
0340 DOMAIN_POWER_GATE, power_gate);
0341
0342 REG_WAIT(DOMAIN18_PG_STATUS,
0343 DOMAIN_PGFSM_PWR_STATUS, pwr_status,
0344 1, 1000);
0345 break;
0346 default:
0347 BREAK_TO_DEBUGGER();
0348 break;
0349 }
0350
0351 if (org_ip_request_cntl == 0)
0352 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
0353
0354 if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc) {
0355 if (hws->ctx->dc->res_pool->dccg->funcs->disable_dsc && !power_on)
0356 hws->ctx->dc->res_pool->dccg->funcs->disable_dsc(
0357 hws->ctx->dc->res_pool->dccg, dsc_inst);
0358 }
0359
0360 }
0361
0362
0363 void dcn31_enable_power_gating_plane(
0364 struct dce_hwseq *hws,
0365 bool enable)
0366 {
0367 bool force_on = true;
0368 uint32_t org_ip_request_cntl = 0;
0369
0370 if (enable && !hws->ctx->dc->debug.disable_hubp_power_gate)
0371 force_on = false;
0372
0373 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
0374 if (org_ip_request_cntl == 0)
0375 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
0376
0377 REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
0378 REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
0379
0380 REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
0381 REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
0382
0383 force_on = true;
0384 if (enable && !hws->ctx->dc->debug.disable_dsc_power_gate)
0385 force_on = false;
0386
0387
0388 REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
0389 REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
0390 REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);
0391
0392 if (org_ip_request_cntl == 0)
0393 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
0394 }
0395
0396 void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx)
0397 {
0398 bool is_hdmi_tmds;
0399 bool is_dp;
0400
0401 ASSERT(pipe_ctx->stream);
0402
0403 if (pipe_ctx->stream_res.stream_enc == NULL)
0404 return;
0405
0406 is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
0407 is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
0408
0409 if (!is_hdmi_tmds && !is_dp)
0410 return;
0411
0412 if (is_hdmi_tmds)
0413 pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
0414 pipe_ctx->stream_res.stream_enc,
0415 &pipe_ctx->stream_res.encoder_info_frame);
0416 else {
0417 pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets(
0418 pipe_ctx->stream_res.stream_enc,
0419 &pipe_ctx->stream_res.encoder_info_frame);
0420 }
0421 }
0422 void dcn31_z10_save_init(struct dc *dc)
0423 {
0424 union dmub_rb_cmd cmd;
0425
0426 memset(&cmd, 0, sizeof(cmd));
0427 cmd.dcn_restore.header.type = DMUB_CMD__IDLE_OPT;
0428 cmd.dcn_restore.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_SAVE_INIT;
0429
0430 dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
0431 dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
0432 dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
0433 }
0434
0435 void dcn31_z10_restore(const struct dc *dc)
0436 {
0437 union dmub_rb_cmd cmd;
0438
0439
0440
0441
0442
0443 if (!dc_dmub_srv_is_restore_required(dc->ctx->dmub_srv))
0444 return;
0445
0446 memset(&cmd, 0, sizeof(cmd));
0447 cmd.dcn_restore.header.type = DMUB_CMD__IDLE_OPT;
0448 cmd.dcn_restore.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_RESTORE;
0449
0450 dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
0451 dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
0452 dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
0453 }
0454
0455 void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
0456 {
0457 uint32_t power_gate = power_on ? 0 : 1;
0458 uint32_t pwr_status = power_on ? 0 : 2;
0459 uint32_t org_ip_request_cntl;
0460 if (hws->ctx->dc->debug.disable_hubp_power_gate)
0461 return;
0462
0463 if (REG(DOMAIN0_PG_CONFIG) == 0)
0464 return;
0465 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
0466 if (org_ip_request_cntl == 0)
0467 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
0468
0469 switch (hubp_inst) {
0470 case 0:
0471 REG_SET(DOMAIN0_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
0472 REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
0473 break;
0474 case 1:
0475 REG_SET(DOMAIN1_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
0476 REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
0477 break;
0478 case 2:
0479 REG_SET(DOMAIN2_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
0480 REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
0481 break;
0482 case 3:
0483 REG_SET(DOMAIN3_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);
0484 REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);
0485 break;
0486 default:
0487 BREAK_TO_DEBUGGER();
0488 break;
0489 }
0490 if (org_ip_request_cntl == 0)
0491 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
0492 }
0493
0494 int dcn31_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config)
0495 {
0496 struct dcn_hubbub_phys_addr_config config;
0497
0498 config.system_aperture.fb_top = pa_config->system_aperture.fb_top;
0499 config.system_aperture.fb_offset = pa_config->system_aperture.fb_offset;
0500 config.system_aperture.fb_base = pa_config->system_aperture.fb_base;
0501 config.system_aperture.agp_top = pa_config->system_aperture.agp_top;
0502 config.system_aperture.agp_bot = pa_config->system_aperture.agp_bot;
0503 config.system_aperture.agp_base = pa_config->system_aperture.agp_base;
0504 config.gart_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr;
0505 config.gart_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr;
0506
0507 if (pa_config->gart_config.base_addr_is_mc_addr) {
0508
0509 config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr -
0510 pa_config->system_aperture.fb_base +
0511 pa_config->system_aperture.fb_offset;
0512 } else
0513 config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;
0514
0515 return dc->res_pool->hubbub->funcs->init_dchub_sys_ctx(dc->res_pool->hubbub, &config);
0516 }
0517
0518 static void dcn31_reset_back_end_for_pipe(
0519 struct dc *dc,
0520 struct pipe_ctx *pipe_ctx,
0521 struct dc_state *context)
0522 {
0523 struct dc_link *link;
0524
0525 DC_LOGGER_INIT(dc->ctx->logger);
0526 if (pipe_ctx->stream_res.stream_enc == NULL) {
0527 pipe_ctx->stream = NULL;
0528 return;
0529 }
0530 ASSERT(!pipe_ctx->top_pipe);
0531
0532 dc->hwss.set_abm_immediate_disable(pipe_ctx);
0533
0534 pipe_ctx->stream_res.tg->funcs->set_dsc_config(
0535 pipe_ctx->stream_res.tg,
0536 OPTC_DSC_DISABLED, 0, 0);
0537 pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
0538
0539 pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
0540 if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)
0541 pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
0542 pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
0543
0544 if (pipe_ctx->stream_res.tg->funcs->set_drr)
0545 pipe_ctx->stream_res.tg->funcs->set_drr(
0546 pipe_ctx->stream_res.tg, NULL);
0547
0548 if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
0549 link = pipe_ctx->stream->link;
0550
0551
0552
0553
0554
0555
0556 if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
0557 core_link_disable_stream(pipe_ctx);
0558 else if (pipe_ctx->stream_res.audio)
0559 dc->hwss.disable_audio_stream(pipe_ctx);
0560
0561
0562 if (pipe_ctx->stream_res.audio) {
0563
0564 pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
0565
0566
0567 if (dc->caps.dynamic_audio == true) {
0568
0569
0570 update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
0571 pipe_ctx->stream_res.audio, false);
0572 pipe_ctx->stream_res.audio = NULL;
0573 }
0574 }
0575 } else if (pipe_ctx->stream_res.dsc) {
0576 dp_set_dsc_enable(pipe_ctx, false);
0577 }
0578
0579 pipe_ctx->stream = NULL;
0580 DC_LOG_DEBUG("Reset back end for pipe %d, tg:%d\n",
0581 pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst);
0582 }
0583
0584 void dcn31_reset_hw_ctx_wrap(
0585 struct dc *dc,
0586 struct dc_state *context)
0587 {
0588 int i;
0589 struct dce_hwseq *hws = dc->hwseq;
0590
0591
0592 for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
0593 struct pipe_ctx *pipe_ctx_old =
0594 &dc->current_state->res_ctx.pipe_ctx[i];
0595 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
0596
0597 if (!pipe_ctx_old->stream)
0598 continue;
0599
0600 if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe)
0601 continue;
0602
0603 if (!pipe_ctx->stream ||
0604 pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
0605 struct clock_source *old_clk = pipe_ctx_old->clock_source;
0606
0607 dcn31_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
0608 if (hws->funcs.enable_stream_gating)
0609 hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
0610 if (old_clk)
0611 old_clk->funcs->cs_power_down(old_clk);
0612 }
0613 }
0614
0615
0616 link_enc_cfg_set_transient_mode(dc, dc->current_state, context);
0617 }
0618
0619 void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable)
0620 {
0621 if (hws->ctx->dc->debug.hpo_optimization)
0622 REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, !!enable);
0623 }