void dcn201_init_hw(struct dc *dc)
{ int i, j; struct dce_hwseq *hws = dc->hwseq; struct resource_pool *res_pool = dc->res_pool; struct dc_state *context = dc->current_state;
if (res_pool->dccg->funcs->dccg_init)
res_pool->dccg->funcs->dccg_init(res_pool->dccg);
if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
hws->funcs.bios_golden_init(dc);
if (dc->ctx->dc_bios->fw_info_valid) {
res_pool->ref_clocks.xtalin_clock_inKhz =
dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
if (res_pool->hubbub) {
(res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
&res_pool->ref_clocks.dccg_ref_clock_inKhz);
(res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
res_pool->ref_clocks.dccg_ref_clock_inKhz,
&res_pool->ref_clocks.dchub_ref_clock_inKhz);
} else {
res_pool->ref_clocks.dccg_ref_clock_inKhz =
res_pool->ref_clocks.xtalin_clock_inKhz;
res_pool->ref_clocks.dchub_ref_clock_inKhz =
res_pool->ref_clocks.xtalin_clock_inKhz;
}
} else
ASSERT_CRITICAL(false); for (i = 0; i < dc->link_count; i++) { /* Power up AND update implementation according to the *requiredsignal(whichmaybedifferentfromthe *defaultsignalonconnector).
*/ struct dc_link *link = dc->links[i];
link->link_enc->funcs->hw_init(link->link_enc);
} if (hws->fb_offset.quad_part == 0)
read_mmhub_vm_setup(hws);
/* Blank pixel data with OPP DPG */ for (i = 0; i < res_pool->timing_generator_count; i++) { struct timing_generator *tg = res_pool->timing_generators[i];
if (tg->funcs->is_tg_enabled(tg)) {
dcn201_init_blank(dc, tg);
}
}
for (i = 0; i < res_pool->timing_generator_count; i++) { struct timing_generator *tg = res_pool->timing_generators[i];
if (tg->funcs->is_tg_enabled(tg))
tg->funcs->lock(tg);
}
for (i = 0; i < res_pool->pipe_count; i++) { struct dpp *dpp = res_pool->dpps[i];
dpp->funcs->dpp_reset(dpp);
}
/* Reset all MPCC muxes */
res_pool->mpc->funcs->mpc_init(res_pool->mpc);
/* initialize OPP mpc_tree parameter */ for (i = 0; i < res_pool->res_cap->num_opp; i++) {
res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
res_pool->opps[i]->mpc_tree_params.opp_list = NULL; for (j = 0; j < MAX_PIPES; j++)
res_pool->opps[i]->mpcc_disconnect_pending[j] = false;
}
for (i = 0; i < res_pool->timing_generator_count; i++) { struct timing_generator *tg = res_pool->timing_generators[i]; struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; struct hubp *hubp = res_pool->hubps[i]; struct dpp *dpp = res_pool->dpps[i];
res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
pipe_ctx->stream_res.opp = res_pool->opps[i]; /*To do: number of MPCC != number of opp*/
hws->funcs.plane_atomic_disconnect(dc, context, pipe_ctx);
}
/* initialize DWB pointer to MCIF_WB */ for (i = 0; i < res_pool->res_cap->num_dwb; i++)
res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i];
for (i = 0; i < res_pool->timing_generator_count; i++) { struct timing_generator *tg = res_pool->timing_generators[i];
if (tg->funcs->is_tg_enabled(tg))
tg->funcs->unlock(tg);
}
for (i = 0; i < res_pool->pipe_count; i++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
for (i = 0; i < res_pool->timing_generator_count; i++) { struct timing_generator *tg = res_pool->timing_generators[i];
tg->funcs->tg_init(tg);
}
for (i = 0; i < res_pool->audio_count; i++) { struct audio *audio = res_pool->audios[i];
audio->funcs->hw_init(audio);
}
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */
REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
}
/* trigger HW to start disconnect plane from stream on the next vsync */ void dcn201_plane_atomic_disconnect(struct dc *dc, struct dc_state *state, struct pipe_ctx *pipe_ctx)
{ struct dce_hwseq *hws = dc->hwseq; struct hubp *hubp = pipe_ctx->plane_res.hubp; int dpp_id = pipe_ctx->plane_res.dpp->inst; struct mpc *mpc = dc->res_pool->mpc; struct mpc_tree *mpc_tree_params; struct mpcc *mpcc_to_remove = NULL; struct output_pixel_processor *opp = pipe_ctx->stream_res.opp; bool mpcc_removed = false;
mpc_tree_params = &(opp->mpc_tree_params);
/* check if this plane is being used by an MPCC in the secondary blending chain */ if (mpc->funcs->get_mpcc_for_dpp_from_secondary)
mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);
/* remove MPCC from secondary if being used */ if (mpcc_to_remove != NULL && mpc->funcs->remove_mpcc_from_secondary) {
mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, mpcc_to_remove);
mpcc_removed = true;
}
/* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */
mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id); if (mpcc_to_remove != NULL) {
mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
mpcc_removed = true;
}
/*Already reset*/ if (mpcc_removed == false) return;
/* DCN1.0 has output CM before MPC which seems to screw with *pre-multipliedalpha.Thisisaw/ahopefullyunnecessaryforDCN2.
*/
blnd_cfg.pre_multiplied_alpha = per_pixel_alpha;
/* If there is no full update, don't need to touch MPC tree*/ if (!pipe_ctx->plane_state->update_flags.bits.full_update) {
dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id); return;
}
/* check if this plane is being used by an MPCC in the secondary blending chain */ if (mpc->funcs->get_mpcc_for_dpp_from_secondary)
remove_mpcc = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);
/* remove MPCC from secondary if being used */ if (remove_mpcc != NULL && mpc->funcs->remove_mpcc_from_secondary)
mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, remove_mpcc);
/* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */
remove_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id); /* remove MPCC if being used */
if (remove_mpcc != NULL)
mpc->funcs->remove_mpcc(mpc, mpc_tree_params, remove_mpcc); else if (dc->debug.sanity_checks)
mpc->funcs->assert_mpcc_idle_before_connect(
dc->res_pool->mpc, mpcc_id);
/* Call MPC to insert new plane */
dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);
new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,
mpc_tree_params,
&blnd_cfg,
NULL,
NULL,
dpp_id,
mpcc_id);
if (dc_is_dp_signal(pipe_ctx->stream->signal)) { /*check whether it is half the rate*/ if (pipe_ctx->stream_res.tg->funcs->is_two_pixels_per_container(&stream->timing))
params.timing.pix_clk_100hz /= 2;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.