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 #include "dm_services.h"
0027 #include "basics/dc_common.h"
0028 #include "core_types.h"
0029 #include "resource.h"
0030 #include "dcn201_hwseq.h"
0031 #include "dcn201_optc.h"
0032 #include "dce/dce_hwseq.h"
0033 #include "hubp.h"
0034 #include "dchubbub.h"
0035 #include "timing_generator.h"
0036 #include "opp.h"
0037 #include "ipp.h"
0038 #include "mpc.h"
0039 #include "dccg.h"
0040 #include "clk_mgr.h"
0041 #include "reg_helper.h"
0042
0043 #define CTX \
0044 hws->ctx
0045
0046 #define REG(reg)\
0047 hws->regs->reg
0048
0049 #define DC_LOGGER \
0050 dc->ctx->logger
0051
0052 #undef FN
0053 #define FN(reg_name, field_name) \
0054 hws->shifts->field_name, hws->masks->field_name
0055
0056 static bool patch_address_for_sbs_tb_stereo(
0057 struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr)
0058 {
0059 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
0060 bool sec_split = pipe_ctx->top_pipe &&
0061 pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;
0062
0063 if (sec_split && plane_state->address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
0064 (pipe_ctx->stream->timing.timing_3d_format ==
0065 TIMING_3D_FORMAT_SIDE_BY_SIDE ||
0066 pipe_ctx->stream->timing.timing_3d_format ==
0067 TIMING_3D_FORMAT_TOP_AND_BOTTOM)) {
0068 *addr = plane_state->address.grph_stereo.left_addr;
0069 plane_state->address.grph_stereo.left_addr =
0070 plane_state->address.grph_stereo.right_addr;
0071 return true;
0072 } else {
0073 if (pipe_ctx->stream->view_format != VIEW_3D_FORMAT_NONE &&
0074 plane_state->address.type != PLN_ADDR_TYPE_GRPH_STEREO) {
0075 plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO;
0076 plane_state->address.grph_stereo.right_addr =
0077 plane_state->address.grph_stereo.left_addr;
0078 plane_state->address.grph_stereo.right_meta_addr =
0079 plane_state->address.grph_stereo.left_meta_addr;
0080 }
0081 }
0082 return false;
0083 }
0084
0085 static void gpu_addr_to_uma(struct dce_hwseq *hwseq,
0086 PHYSICAL_ADDRESS_LOC *addr)
0087 {
0088 bool is_in_uma;
0089
0090 if (hwseq->fb_base.quad_part <= addr->quad_part &&
0091 addr->quad_part < hwseq->fb_top.quad_part) {
0092 addr->quad_part -= hwseq->fb_base.quad_part;
0093 addr->quad_part += hwseq->fb_offset.quad_part;
0094 is_in_uma = true;
0095 } else if (hwseq->fb_offset.quad_part <= addr->quad_part &&
0096 addr->quad_part <= hwseq->uma_top.quad_part) {
0097 is_in_uma = true;
0098 } else {
0099 is_in_uma = false;
0100 }
0101 }
0102
0103 static void plane_address_in_gpu_space_to_uma(struct dce_hwseq *hwseq,
0104 struct dc_plane_address *addr)
0105 {
0106 switch (addr->type) {
0107 case PLN_ADDR_TYPE_GRAPHICS:
0108 gpu_addr_to_uma(hwseq, &addr->grph.addr);
0109 gpu_addr_to_uma(hwseq, &addr->grph.meta_addr);
0110 break;
0111 case PLN_ADDR_TYPE_GRPH_STEREO:
0112 gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_addr);
0113 gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_meta_addr);
0114 gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_addr);
0115 gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_meta_addr);
0116 break;
0117 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
0118 gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_addr);
0119 gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_meta_addr);
0120 gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_addr);
0121 gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_meta_addr);
0122 break;
0123 default:
0124 BREAK_TO_DEBUGGER();
0125 break;
0126 }
0127 }
0128
0129 void dcn201_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx)
0130 {
0131 bool addr_patched = false;
0132 PHYSICAL_ADDRESS_LOC addr;
0133 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
0134 struct dce_hwseq *hws = dc->hwseq;
0135 struct dc_plane_address uma;
0136
0137 if (plane_state == NULL)
0138 return;
0139
0140 uma = plane_state->address;
0141 addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
0142
0143 plane_address_in_gpu_space_to_uma(hws, &uma);
0144
0145 pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
0146 pipe_ctx->plane_res.hubp,
0147 &uma,
0148 plane_state->flip_immediate);
0149
0150 plane_state->status.requested_address = plane_state->address;
0151
0152 if (plane_state->flip_immediate)
0153 plane_state->status.current_address = plane_state->address;
0154
0155 if (addr_patched)
0156 pipe_ctx->plane_state->address.grph_stereo.left_addr = addr;
0157 }
0158
0159
0160 void dcn201_init_blank(
0161 struct dc *dc,
0162 struct timing_generator *tg)
0163 {
0164 struct dce_hwseq *hws = dc->hwseq;
0165 enum dc_color_space color_space;
0166 struct tg_color black_color = {0};
0167 struct output_pixel_processor *opp = NULL;
0168 uint32_t num_opps, opp_id_src0, opp_id_src1;
0169 uint32_t otg_active_width, otg_active_height;
0170
0171
0172 color_space = COLOR_SPACE_SRGB;
0173 color_space_to_black_color(dc, color_space, &black_color);
0174
0175
0176 tg->funcs->get_otg_active_size(tg,
0177 &otg_active_width,
0178 &otg_active_height);
0179
0180
0181 tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);
0182 ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp);
0183 opp = dc->res_pool->opps[opp_id_src0];
0184
0185 opp->funcs->opp_set_disp_pattern_generator(
0186 opp,
0187 CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,
0188 CONTROLLER_DP_COLOR_SPACE_UDEFINED,
0189 COLOR_DEPTH_UNDEFINED,
0190 &black_color,
0191 otg_active_width,
0192 otg_active_height,
0193 0);
0194
0195 hws->funcs.wait_for_blank_complete(opp);
0196 }
0197
0198 static void read_mmhub_vm_setup(struct dce_hwseq *hws)
0199 {
0200 uint32_t fb_base = REG_READ(MC_VM_FB_LOCATION_BASE);
0201 uint32_t fb_top = REG_READ(MC_VM_FB_LOCATION_TOP);
0202 uint32_t fb_offset = REG_READ(MC_VM_FB_OFFSET);
0203
0204
0205 fb_top++;
0206
0207
0208 hws->fb_base.low_part = fb_base;
0209 hws->fb_base.quad_part <<= 24;
0210
0211 hws->fb_top.low_part = fb_top;
0212 hws->fb_top.quad_part <<= 24;
0213 hws->fb_offset.low_part = fb_offset;
0214 hws->fb_offset.quad_part <<= 24;
0215
0216 hws->uma_top.quad_part = hws->fb_top.quad_part
0217 - hws->fb_base.quad_part + hws->fb_offset.quad_part;
0218 }
0219
0220 void dcn201_init_hw(struct dc *dc)
0221 {
0222 int i, j;
0223 struct dce_hwseq *hws = dc->hwseq;
0224 struct resource_pool *res_pool = dc->res_pool;
0225 struct dc_state *context = dc->current_state;
0226
0227 if (res_pool->dccg->funcs->dccg_init)
0228 res_pool->dccg->funcs->dccg_init(res_pool->dccg);
0229
0230 if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
0231 dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
0232
0233 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
0234 REG_WRITE(RBBMIF_TIMEOUT_DIS, 0xFFFFFFFF);
0235 REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF);
0236
0237 hws->funcs.dccg_init(hws);
0238
0239 REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
0240 REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
0241 REG_WRITE(REFCLK_CNTL, 0);
0242 } else {
0243 hws->funcs.bios_golden_init(dc);
0244
0245 if (dc->ctx->dc_bios->fw_info_valid) {
0246 res_pool->ref_clocks.xtalin_clock_inKhz =
0247 dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
0248
0249 if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
0250 if (res_pool->dccg && res_pool->hubbub) {
0251 (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
0252 dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
0253 &res_pool->ref_clocks.dccg_ref_clock_inKhz);
0254
0255 (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
0256 res_pool->ref_clocks.dccg_ref_clock_inKhz,
0257 &res_pool->ref_clocks.dchub_ref_clock_inKhz);
0258 } else {
0259 res_pool->ref_clocks.dccg_ref_clock_inKhz =
0260 res_pool->ref_clocks.xtalin_clock_inKhz;
0261 res_pool->ref_clocks.dchub_ref_clock_inKhz =
0262 res_pool->ref_clocks.xtalin_clock_inKhz;
0263 }
0264 }
0265 } else
0266 ASSERT_CRITICAL(false);
0267 for (i = 0; i < dc->link_count; i++) {
0268
0269
0270
0271
0272 struct dc_link *link = dc->links[i];
0273
0274 link->link_enc->funcs->hw_init(link->link_enc);
0275 }
0276 if (hws->fb_offset.quad_part == 0)
0277 read_mmhub_vm_setup(hws);
0278 }
0279
0280
0281 for (i = 0; i < res_pool->timing_generator_count; i++) {
0282 struct timing_generator *tg = res_pool->timing_generators[i];
0283
0284 if (tg->funcs->is_tg_enabled(tg)) {
0285 dcn201_init_blank(dc, tg);
0286 }
0287 }
0288
0289 for (i = 0; i < res_pool->timing_generator_count; i++) {
0290 struct timing_generator *tg = res_pool->timing_generators[i];
0291
0292 if (tg->funcs->is_tg_enabled(tg))
0293 tg->funcs->lock(tg);
0294 }
0295
0296 for (i = 0; i < res_pool->pipe_count; i++) {
0297 struct dpp *dpp = res_pool->dpps[i];
0298
0299 dpp->funcs->dpp_reset(dpp);
0300 }
0301
0302
0303 res_pool->mpc->funcs->mpc_init(res_pool->mpc);
0304
0305
0306 for (i = 0; i < res_pool->res_cap->num_opp; i++) {
0307 res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
0308 res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
0309 for (j = 0; j < MAX_PIPES; j++)
0310 res_pool->opps[i]->mpcc_disconnect_pending[j] = false;
0311 }
0312
0313 for (i = 0; i < res_pool->timing_generator_count; i++) {
0314 struct timing_generator *tg = res_pool->timing_generators[i];
0315 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
0316 struct hubp *hubp = res_pool->hubps[i];
0317 struct dpp *dpp = res_pool->dpps[i];
0318
0319 pipe_ctx->stream_res.tg = tg;
0320 pipe_ctx->pipe_idx = i;
0321
0322 pipe_ctx->plane_res.hubp = hubp;
0323 pipe_ctx->plane_res.dpp = dpp;
0324 pipe_ctx->plane_res.mpcc_inst = dpp->inst;
0325 hubp->mpcc_id = dpp->inst;
0326 hubp->opp_id = OPP_ID_INVALID;
0327 hubp->power_gated = false;
0328 pipe_ctx->stream_res.opp = NULL;
0329
0330 hubp->funcs->hubp_init(hubp);
0331
0332 res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
0333 pipe_ctx->stream_res.opp = res_pool->opps[i];
0334
0335 hws->funcs.plane_atomic_disconnect(dc, pipe_ctx);
0336 }
0337
0338
0339 for (i = 0; i < res_pool->res_cap->num_dwb; i++)
0340 res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i];
0341
0342 for (i = 0; i < res_pool->timing_generator_count; i++) {
0343 struct timing_generator *tg = res_pool->timing_generators[i];
0344
0345 if (tg->funcs->is_tg_enabled(tg))
0346 tg->funcs->unlock(tg);
0347 }
0348
0349 for (i = 0; i < res_pool->pipe_count; i++) {
0350 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
0351
0352 dc->hwss.disable_plane(dc, pipe_ctx);
0353
0354 pipe_ctx->stream_res.tg = NULL;
0355 pipe_ctx->plane_res.hubp = NULL;
0356 }
0357
0358 for (i = 0; i < res_pool->timing_generator_count; i++) {
0359 struct timing_generator *tg = res_pool->timing_generators[i];
0360
0361 tg->funcs->tg_init(tg);
0362 }
0363
0364
0365 if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
0366 return;
0367
0368 for (i = 0; i < res_pool->audio_count; i++) {
0369 struct audio *audio = res_pool->audios[i];
0370
0371 audio->funcs->hw_init(audio);
0372 }
0373
0374
0375 REG_WRITE(DIO_MEM_PWR_CTRL, 0);
0376
0377 if (!dc->debug.disable_clock_gate) {
0378
0379 REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
0380
0381 REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
0382
0383 REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
0384 }
0385 }
0386
0387
0388 void dcn201_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
0389 {
0390 struct dce_hwseq *hws = dc->hwseq;
0391 struct hubp *hubp = pipe_ctx->plane_res.hubp;
0392 int dpp_id = pipe_ctx->plane_res.dpp->inst;
0393 struct mpc *mpc = dc->res_pool->mpc;
0394 struct mpc_tree *mpc_tree_params;
0395 struct mpcc *mpcc_to_remove = NULL;
0396 struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
0397 bool mpcc_removed = false;
0398
0399 mpc_tree_params = &(opp->mpc_tree_params);
0400
0401
0402 if (mpc->funcs->get_mpcc_for_dpp_from_secondary)
0403 mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);
0404
0405
0406 if (mpcc_to_remove != NULL && mpc->funcs->remove_mpcc_from_secondary) {
0407 mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, mpcc_to_remove);
0408 mpcc_removed = true;
0409 }
0410
0411
0412 mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
0413 if (mpcc_to_remove != NULL) {
0414 mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
0415 mpcc_removed = true;
0416 }
0417
0418
0419 if (mpcc_removed == false)
0420 return;
0421
0422 if (opp != NULL)
0423 opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
0424
0425 dc->optimized_required = true;
0426
0427 if (hubp->funcs->hubp_disconnect)
0428 hubp->funcs->hubp_disconnect(hubp);
0429
0430 if (dc->debug.sanity_checks)
0431 hws->funcs.verify_allow_pstate_change_high(dc);
0432 }
0433
0434 void dcn201_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
0435 {
0436 struct hubp *hubp = pipe_ctx->plane_res.hubp;
0437 struct mpcc_blnd_cfg blnd_cfg;
0438 bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
0439 int mpcc_id, dpp_id;
0440 struct mpcc *new_mpcc;
0441 struct mpcc *remove_mpcc = NULL;
0442 struct mpc *mpc = dc->res_pool->mpc;
0443 struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
0444
0445 if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) {
0446 get_hdr_visual_confirm_color(
0447 pipe_ctx, &blnd_cfg.black_color);
0448 } else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {
0449 get_surface_visual_confirm_color(
0450 pipe_ctx, &blnd_cfg.black_color);
0451 } else {
0452 color_space_to_black_color(
0453 dc, pipe_ctx->stream->output_color_space,
0454 &blnd_cfg.black_color);
0455 }
0456
0457 if (per_pixel_alpha)
0458 blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
0459 else
0460 blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
0461
0462 blnd_cfg.overlap_only = false;
0463
0464 if (pipe_ctx->plane_state->global_alpha_value)
0465 blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value;
0466 else
0467 blnd_cfg.global_alpha = 0xff;
0468
0469 blnd_cfg.global_gain = 0xff;
0470 blnd_cfg.background_color_bpc = 4;
0471 blnd_cfg.bottom_gain_mode = 0;
0472 blnd_cfg.top_gain = 0x1f000;
0473 blnd_cfg.bottom_inside_gain = 0x1f000;
0474 blnd_cfg.bottom_outside_gain = 0x1f000;
0475
0476 blnd_cfg.black_color.color_b_cb = 0;
0477 blnd_cfg.black_color.color_g_y = 0;
0478 blnd_cfg.black_color.color_r_cr = 0;
0479
0480
0481
0482
0483 blnd_cfg.pre_multiplied_alpha = per_pixel_alpha;
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 dpp_id = hubp->inst;
0494 mpcc_id = dpp_id;
0495
0496
0497 if (!pipe_ctx->plane_state->update_flags.bits.full_update) {
0498 dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id);
0499 mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);
0500 return;
0501 }
0502
0503
0504 if (mpc->funcs->get_mpcc_for_dpp_from_secondary)
0505 remove_mpcc = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);
0506
0507
0508 if (remove_mpcc != NULL && mpc->funcs->remove_mpcc_from_secondary)
0509 mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, remove_mpcc);
0510
0511
0512 remove_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
0513
0514
0515 if (remove_mpcc != NULL)
0516 mpc->funcs->remove_mpcc(mpc, mpc_tree_params, remove_mpcc);
0517 else
0518 if (dc->debug.sanity_checks)
0519 mpc->funcs->assert_mpcc_idle_before_connect(
0520 dc->res_pool->mpc, mpcc_id);
0521
0522
0523 dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id);
0524 new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,
0525 mpc_tree_params,
0526 &blnd_cfg,
0527 NULL,
0528 NULL,
0529 dpp_id,
0530 mpcc_id);
0531
0532 ASSERT(new_mpcc != NULL);
0533 hubp->opp_id = pipe_ctx->stream_res.opp->inst;
0534 hubp->mpcc_id = mpcc_id;
0535 }
0536
0537 void dcn201_pipe_control_lock(
0538 struct dc *dc,
0539 struct pipe_ctx *pipe,
0540 bool lock)
0541 {
0542 struct dce_hwseq *hws = dc->hwseq;
0543 struct hubp *hubp = NULL;
0544 hubp = dc->res_pool->hubps[pipe->pipe_idx];
0545
0546
0547
0548 if (pipe->top_pipe)
0549 return;
0550
0551 if (dc->debug.sanity_checks)
0552 hws->funcs.verify_allow_pstate_change_high(dc);
0553
0554 if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
0555 if (lock)
0556 pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
0557 else
0558 pipe->stream_res.tg->funcs->triplebuffer_unlock(pipe->stream_res.tg);
0559 } else {
0560 if (lock)
0561 pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);
0562 else
0563 pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);
0564 }
0565
0566 if (dc->debug.sanity_checks)
0567 hws->funcs.verify_allow_pstate_change_high(dc);
0568 }
0569
0570 void dcn201_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
0571 {
0572 struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
0573
0574 gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq, &attributes->address);
0575
0576 pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
0577 pipe_ctx->plane_res.hubp, attributes);
0578 pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
0579 pipe_ctx->plane_res.dpp, attributes);
0580 }
0581
0582 void dcn201_set_dmdata_attributes(struct pipe_ctx *pipe_ctx)
0583 {
0584 struct dc_dmdata_attributes attr = { 0 };
0585 struct hubp *hubp = pipe_ctx->plane_res.hubp;
0586
0587 gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq,
0588 &pipe_ctx->stream->dmdata_address);
0589
0590 attr.dmdata_mode = DMDATA_HW_MODE;
0591 attr.dmdata_size =
0592 dc_is_hdmi_signal(pipe_ctx->stream->signal) ? 32 : 36;
0593 attr.address.quad_part =
0594 pipe_ctx->stream->dmdata_address.quad_part;
0595 attr.dmdata_dl_delta = 0;
0596 attr.dmdata_qos_mode = 0;
0597 attr.dmdata_qos_level = 0;
0598 attr.dmdata_repeat = 1;
0599 attr.dmdata_updated = 1;
0600 attr.dmdata_sw_data = NULL;
0601
0602 hubp->funcs->dmdata_set_attributes(hubp, &attr);
0603 }
0604
0605 void dcn201_unblank_stream(struct pipe_ctx *pipe_ctx,
0606 struct dc_link_settings *link_settings)
0607 {
0608 struct encoder_unblank_param params = { { 0 } };
0609 struct dc_stream_state *stream = pipe_ctx->stream;
0610 struct dc_link *link = stream->link;
0611 struct dce_hwseq *hws = link->dc->hwseq;
0612
0613
0614 params.timing = pipe_ctx->stream->timing;
0615
0616 params.link_settings.link_rate = link_settings->link_rate;
0617
0618 if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
0619
0620 if (optc201_is_two_pixels_per_containter(&stream->timing))
0621 params.timing.pix_clk_100hz /= 2;
0622
0623 pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, ¶ms);
0624 }
0625
0626 if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
0627 hws->funcs.edp_backlight_control(link, true);
0628 }
0629 }