mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 18:10:52 +07:00
drm/amd/display: Make init_hw and init_pipes generic for seamless boot
[Why] For seamless boot the init_hw sequence must be split into actual hardware vs pipes, in order to defer pipe initialization to set mode and skip of pipe-destructive sequences [How] made dcn10_init_hw and dcn10_init_pipes generic for future dcns to inherit deleted dcn20 specific versions. This is part 1 of a 2 partimplementation of seamless boot Signed-off-by: Martin Leung <martin.leung@amd.com> Reviewed-by: Jun Lei <Jun.Lei@amd.com> Acked-by: Leo Li <sunpeng.li@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
61e29b21cb
commit
8a31820b12
@ -731,7 +731,7 @@ static enum bp_result link_transmitter_control(
|
||||
* @brief
|
||||
* eDP only.
|
||||
*/
|
||||
void hwss_edp_wait_for_hpd_ready(
|
||||
void dce110_edp_wait_for_hpd_ready(
|
||||
struct dc_link *link,
|
||||
bool power_up)
|
||||
{
|
||||
@ -799,7 +799,7 @@ void hwss_edp_wait_for_hpd_ready(
|
||||
}
|
||||
}
|
||||
|
||||
void hwss_edp_power_control(
|
||||
void dce110_edp_power_control(
|
||||
struct dc_link *link,
|
||||
bool power_up)
|
||||
{
|
||||
@ -881,7 +881,7 @@ void hwss_edp_power_control(
|
||||
* @brief
|
||||
* eDP only. Control the backlight of the eDP panel
|
||||
*/
|
||||
void hwss_edp_backlight_control(
|
||||
void dce110_edp_backlight_control(
|
||||
struct dc_link *link,
|
||||
bool enable)
|
||||
{
|
||||
@ -2758,9 +2758,9 @@ static const struct hw_sequencer_funcs dce110_funcs = {
|
||||
.setup_stereo = NULL,
|
||||
.set_avmute = dce110_set_avmute,
|
||||
.wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
|
||||
.edp_backlight_control = hwss_edp_backlight_control,
|
||||
.edp_power_control = hwss_edp_power_control,
|
||||
.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
|
||||
.edp_backlight_control = dce110_edp_backlight_control,
|
||||
.edp_power_control = dce110_edp_power_control,
|
||||
.edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
|
||||
.set_cursor_position = dce110_set_cursor_position,
|
||||
.set_cursor_attribute = dce110_set_cursor_attribute
|
||||
};
|
||||
|
@ -73,15 +73,15 @@ void dce110_optimize_bandwidth(
|
||||
|
||||
void dp_receiver_power_ctrl(struct dc_link *link, bool on);
|
||||
|
||||
void hwss_edp_power_control(
|
||||
void dce110_edp_power_control(
|
||||
struct dc_link *link,
|
||||
bool power_up);
|
||||
|
||||
void hwss_edp_backlight_control(
|
||||
void dce110_edp_backlight_control(
|
||||
struct dc_link *link,
|
||||
bool enable);
|
||||
|
||||
void hwss_edp_wait_for_hpd_ready(
|
||||
void dce110_edp_wait_for_hpd_ready(
|
||||
struct dc_link *link,
|
||||
bool power_up);
|
||||
|
||||
|
@ -104,7 +104,7 @@ void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow)
|
||||
DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, !allow);
|
||||
}
|
||||
|
||||
bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubbub)
|
||||
bool hubbub1_is_allow_self_refresh_enabled(struct hubbub *hubbub)
|
||||
{
|
||||
struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
|
||||
uint32_t enable = 0;
|
||||
@ -945,6 +945,8 @@ static const struct hubbub_funcs hubbub1_funcs = {
|
||||
.get_dcc_compression_cap = hubbub1_get_dcc_compression_cap,
|
||||
.wm_read_state = hubbub1_wm_read_state,
|
||||
.program_watermarks = hubbub1_program_watermarks,
|
||||
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
|
||||
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
|
||||
};
|
||||
|
||||
void hubbub1_construct(struct hubbub *hubbub,
|
||||
|
@ -247,7 +247,7 @@ void hubbub1_program_watermarks(
|
||||
|
||||
void hubbub1_allow_self_refresh_control(struct hubbub *hubbub, bool allow);
|
||||
|
||||
bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubub);
|
||||
bool hubbub1_is_allow_self_refresh_enabled(struct hubbub *hubub);
|
||||
|
||||
void hubbub1_toggle_watermark_change_req(
|
||||
struct hubbub *hubbub);
|
||||
|
@ -438,7 +438,7 @@ bool dcn10_did_underflow_occur(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void enable_power_gating_plane(
|
||||
static void dcn10_enable_power_gating_plane(
|
||||
struct dce_hwseq *hws,
|
||||
bool enable)
|
||||
{
|
||||
@ -460,7 +460,7 @@ static void enable_power_gating_plane(
|
||||
REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on);
|
||||
}
|
||||
|
||||
static void disable_vga(
|
||||
static void dcn10_disable_vga(
|
||||
struct dce_hwseq *hws)
|
||||
{
|
||||
unsigned int in_vga1_mode = 0;
|
||||
@ -493,7 +493,7 @@ static void disable_vga(
|
||||
REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_RENDER_START, 1);
|
||||
}
|
||||
|
||||
static void dpp_pg_control(
|
||||
static void dcn10_dpp_pg_control(
|
||||
struct dce_hwseq *hws,
|
||||
unsigned int dpp_inst,
|
||||
bool power_on)
|
||||
@ -545,7 +545,7 @@ static void dpp_pg_control(
|
||||
}
|
||||
}
|
||||
|
||||
static void hubp_pg_control(
|
||||
static void dcn10_hubp_pg_control(
|
||||
struct dce_hwseq *hws,
|
||||
unsigned int hubp_inst,
|
||||
bool power_on)
|
||||
@ -605,8 +605,8 @@ static void power_on_plane(
|
||||
if (REG(DC_IP_REQUEST_CNTL)) {
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0,
|
||||
IP_REQUEST_EN, 1);
|
||||
dpp_pg_control(hws, plane_id, true);
|
||||
hubp_pg_control(hws, plane_id, true);
|
||||
hws->ctx->dc->hwss.dpp_pg_control(hws, plane_id, true);
|
||||
hws->ctx->dc->hwss.hubp_pg_control(hws, plane_id, true);
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0,
|
||||
IP_REQUEST_EN, 0);
|
||||
DC_LOG_DEBUG(
|
||||
@ -627,7 +627,7 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc)
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0,
|
||||
IP_REQUEST_EN, 1);
|
||||
|
||||
hubp_pg_control(hws, 0, false);
|
||||
dc->hwss.hubp_pg_control(hws, 0, false);
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0,
|
||||
IP_REQUEST_EN, 0);
|
||||
|
||||
@ -656,7 +656,7 @@ static void apply_DEGVIDCN10_253_wa(struct dc *dc)
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0,
|
||||
IP_REQUEST_EN, 1);
|
||||
|
||||
hubp_pg_control(hws, 0, true);
|
||||
dc->hwss.hubp_pg_control(hws, 0, true);
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0,
|
||||
IP_REQUEST_EN, 0);
|
||||
|
||||
@ -664,10 +664,23 @@ static void apply_DEGVIDCN10_253_wa(struct dc *dc)
|
||||
hws->wa_state.DEGVIDCN10_253_applied = true;
|
||||
}
|
||||
|
||||
static void bios_golden_init(struct dc *dc)
|
||||
static void dcn10_bios_golden_init(struct dc *dc)
|
||||
{
|
||||
struct dc_bios *bp = dc->ctx->dc_bios;
|
||||
int i;
|
||||
bool allow_self_fresh_force_enable = true;
|
||||
|
||||
if (dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled)
|
||||
allow_self_fresh_force_enable =
|
||||
dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub);
|
||||
|
||||
|
||||
/* WA for making DF sleep when idle after resume from S0i3.
|
||||
* DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by
|
||||
* command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0
|
||||
* before calling command table and it changed to 1 after,
|
||||
* it should be set back to 0.
|
||||
*/
|
||||
|
||||
/* initialize dcn global */
|
||||
bp->funcs->enable_disp_power_gating(bp,
|
||||
@ -678,6 +691,12 @@ static void bios_golden_init(struct dc *dc)
|
||||
bp->funcs->enable_disp_power_gating(bp,
|
||||
CONTROLLER_ID_D0 + i, ASIC_PIPE_DISABLE);
|
||||
}
|
||||
|
||||
if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
|
||||
if (allow_self_fresh_force_enable == false &&
|
||||
dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub))
|
||||
dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, true);
|
||||
|
||||
}
|
||||
|
||||
static void false_optc_underflow_wa(
|
||||
@ -971,7 +990,7 @@ void hwss1_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
dcn10_verify_allow_pstate_change_high(dc);
|
||||
}
|
||||
|
||||
static void plane_atomic_power_down(struct dc *dc,
|
||||
static void dcn10_plane_atomic_power_down(struct dc *dc,
|
||||
struct dpp *dpp,
|
||||
struct hubp *hubp)
|
||||
{
|
||||
@ -981,8 +1000,8 @@ static void plane_atomic_power_down(struct dc *dc,
|
||||
if (REG(DC_IP_REQUEST_CNTL)) {
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0,
|
||||
IP_REQUEST_EN, 1);
|
||||
dpp_pg_control(hws, dpp->inst, false);
|
||||
hubp_pg_control(hws, hubp->inst, false);
|
||||
dc->hwss.dpp_pg_control(hws, dpp->inst, false);
|
||||
dc->hwss.hubp_pg_control(hws, hubp->inst, false);
|
||||
dpp->funcs->dpp_reset(dpp);
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0,
|
||||
IP_REQUEST_EN, 0);
|
||||
@ -994,7 +1013,7 @@ static void plane_atomic_power_down(struct dc *dc,
|
||||
/* disable HW used by plane.
|
||||
* note: cannot disable until disconnect is complete
|
||||
*/
|
||||
static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
static void dcn10_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
||||
struct dpp *dpp = pipe_ctx->plane_res.dpp;
|
||||
@ -1014,7 +1033,7 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
hubp->power_gated = true;
|
||||
dc->optimized_required = false; /* We're powering off, no need to optimize */
|
||||
|
||||
plane_atomic_power_down(dc,
|
||||
dc->hwss.plane_atomic_power_down(dc,
|
||||
pipe_ctx->plane_res.dpp,
|
||||
pipe_ctx->plane_res.hubp);
|
||||
|
||||
@ -1033,7 +1052,7 @@ static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
|
||||
return;
|
||||
|
||||
plane_atomic_disable(dc, pipe_ctx);
|
||||
dc->hwss.plane_atomic_disable(dc, pipe_ctx);
|
||||
|
||||
apply_DEGVIDCN10_253_wa(dc);
|
||||
|
||||
@ -1068,9 +1087,14 @@ static void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
|
||||
* command table.
|
||||
*/
|
||||
if (tg->funcs->is_tg_enabled(tg)) {
|
||||
tg->funcs->lock(tg);
|
||||
tg->funcs->set_blank(tg, true);
|
||||
hwss_wait_for_blank_complete(tg);
|
||||
if (dc->hwss.init_blank != NULL) {
|
||||
dc->hwss.init_blank(dc, tg);
|
||||
tg->funcs->lock(tg);
|
||||
} else {
|
||||
tg->funcs->lock(tg);
|
||||
tg->funcs->set_blank(tg, true);
|
||||
hwss_wait_for_blank_complete(tg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1114,12 +1138,12 @@ static void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
|
||||
dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
|
||||
pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
|
||||
|
||||
hwss1_plane_atomic_disconnect(dc, pipe_ctx);
|
||||
dc->hwss.plane_atomic_disconnect(dc, pipe_ctx);
|
||||
|
||||
if (tg->funcs->is_tg_enabled(tg))
|
||||
tg->funcs->unlock(tg);
|
||||
|
||||
dcn10_disable_plane(dc, pipe_ctx);
|
||||
dc->hwss.disable_plane(dc, pipe_ctx);
|
||||
|
||||
pipe_ctx->stream_res.tg = NULL;
|
||||
pipe_ctx->plane_res.hubp = NULL;
|
||||
@ -1135,8 +1159,17 @@ static void dcn10_init_hw(struct dc *dc)
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct dc_bios *dcb = dc->ctx->dc_bios;
|
||||
struct resource_pool *res_pool = dc->res_pool;
|
||||
|
||||
if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
|
||||
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
|
||||
|
||||
// Initialize the dccg
|
||||
if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->dccg_init)
|
||||
dc->res_pool->dccg->funcs->dccg_init(res_pool->dccg);
|
||||
|
||||
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
|
||||
REG_WRITE(REFCLK_CNTL, 0);
|
||||
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
|
||||
REG_WRITE(DIO_MEM_PWR_CTRL, 0);
|
||||
@ -1150,30 +1183,39 @@ static void dcn10_init_hw(struct dc *dc)
|
||||
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
|
||||
}
|
||||
|
||||
enable_power_gating_plane(dc->hwseq, true);
|
||||
//Enable ability to power gate / don't force power on permanently
|
||||
dc->hwss.enable_power_gating_plane(hws, true);
|
||||
|
||||
/* end of FPGA. Below if real ASIC */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dcb->funcs->is_accelerated_mode(dcb)) {
|
||||
bool allow_self_fresh_force_enable =
|
||||
hububu1_is_allow_self_refresh_enabled(
|
||||
dc->res_pool->hubbub);
|
||||
dc->hwss.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;
|
||||
|
||||
bios_golden_init(dc);
|
||||
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
if (res_pool->dccg && res_pool->hubbub) {
|
||||
|
||||
/* WA for making DF sleep when idle after resume from S0i3.
|
||||
* DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by
|
||||
* command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0
|
||||
* before calling command table and it changed to 1 after,
|
||||
* it should be set back to 0.
|
||||
*/
|
||||
if (allow_self_fresh_force_enable == false &&
|
||||
hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub))
|
||||
hubbub1_allow_self_refresh_control(dc->res_pool->hubbub, true);
|
||||
(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);
|
||||
|
||||
disable_vga(dc->hwseq);
|
||||
(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 {
|
||||
// Not all ASICs have DCCG sw component
|
||||
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);
|
||||
dc->hwss.disable_vga(dc->hwseq);
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
@ -1191,6 +1233,13 @@ static void dcn10_init_hw(struct dc *dc)
|
||||
link->link_status.link_active = true;
|
||||
}
|
||||
|
||||
/* Power gate DSCs */
|
||||
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||
for (i = 0; i < res_pool->res_cap->num_dsc; i++)
|
||||
if (dc->hwss.dsc_pg_control != NULL)
|
||||
dc->hwss.dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
|
||||
#endif
|
||||
|
||||
/* If taking control over from VBIOS, we may want to optimize our first
|
||||
* mode set, so we need to skip powering down pipes until we know which
|
||||
* pipes we want to use.
|
||||
@ -1199,10 +1248,21 @@ static void dcn10_init_hw(struct dc *dc)
|
||||
*/
|
||||
if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.power_down_display_on_boot) {
|
||||
dc->hwss.init_pipes(dc, dc->current_state);
|
||||
for (i = 0; i < res_pool->pipe_count; i++) {
|
||||
struct hubp *hubp = res_pool->hubps[i];
|
||||
struct dpp *dpp = res_pool->dpps[i];
|
||||
|
||||
hubp->funcs->hubp_init(hubp);
|
||||
res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;
|
||||
dc->hwss.plane_atomic_power_down(dc, dpp, hubp);
|
||||
}
|
||||
|
||||
apply_DEGVIDCN10_253_wa(dc);
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->res_pool->audio_count; i++) {
|
||||
struct audio *audio = dc->res_pool->audios[i];
|
||||
|
||||
for (i = 0; i < res_pool->audio_count; i++) {
|
||||
struct audio *audio = res_pool->audios[i];
|
||||
|
||||
audio->funcs->hw_init(audio);
|
||||
}
|
||||
@ -1230,7 +1290,7 @@ static void dcn10_init_hw(struct dc *dc)
|
||||
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
|
||||
}
|
||||
|
||||
enable_power_gating_plane(dc->hwseq, true);
|
||||
dc->hwss.enable_power_gating_plane(dc->hwseq, true);
|
||||
|
||||
memset(&dc->clk_mgr->clks, 0, sizeof(dc->clk_mgr->clks));
|
||||
}
|
||||
@ -1789,7 +1849,7 @@ static void dcn10_enable_plane(
|
||||
}
|
||||
}
|
||||
|
||||
static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
|
||||
static void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
int i = 0;
|
||||
struct dpp_grph_csc_adjustment adjust;
|
||||
@ -2220,7 +2280,7 @@ void update_dchubp_dpp(
|
||||
|
||||
if (plane_state->update_flags.bits.full_update) {
|
||||
/*gamut remap*/
|
||||
program_gamut_remap(pipe_ctx);
|
||||
dc->hwss.program_gamut_remap(pipe_ctx);
|
||||
|
||||
dc->hwss.program_output_csc(dc,
|
||||
pipe_ctx,
|
||||
@ -2457,7 +2517,7 @@ static void dcn10_apply_ctx_for_surface(
|
||||
if (old_pipe_ctx->stream_res.tg == tg &&
|
||||
old_pipe_ctx->plane_res.hubp &&
|
||||
old_pipe_ctx->plane_res.hubp->opp_id != OPP_ID_INVALID)
|
||||
dcn10_disable_plane(dc, old_pipe_ctx);
|
||||
dc->hwss.disable_plane(dc, old_pipe_ctx);
|
||||
}
|
||||
|
||||
if ((!pipe_ctx->plane_state ||
|
||||
@ -2505,7 +2565,7 @@ static void dcn10_apply_ctx_for_surface(
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||
if (removed_pipe[i])
|
||||
dcn10_disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
|
||||
dc->hwss.disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||
if (removed_pipe[i]) {
|
||||
@ -2597,7 +2657,7 @@ static void dcn10_optimize_bandwidth(
|
||||
dcn10_verify_allow_pstate_change_high(dc);
|
||||
}
|
||||
|
||||
static void set_drr(struct pipe_ctx **pipe_ctx,
|
||||
static void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
|
||||
int num_pipes, int vmin, int vmax)
|
||||
{
|
||||
int i = 0;
|
||||
@ -2622,7 +2682,7 @@ static void set_drr(struct pipe_ctx **pipe_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
static void get_position(struct pipe_ctx **pipe_ctx,
|
||||
static void dcn10_get_position(struct pipe_ctx **pipe_ctx,
|
||||
int num_pipes,
|
||||
struct crtc_position *position)
|
||||
{
|
||||
@ -2634,7 +2694,7 @@ static void get_position(struct pipe_ctx **pipe_ctx,
|
||||
pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position);
|
||||
}
|
||||
|
||||
static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
|
||||
static void dcn10_set_static_screen_control(struct pipe_ctx **pipe_ctx,
|
||||
int num_pipes, const struct dc_static_screen_events *events)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -3125,7 +3185,7 @@ static void dcn10_get_clock(struct dc *dc,
|
||||
}
|
||||
|
||||
static const struct hw_sequencer_funcs dcn10_funcs = {
|
||||
.program_gamut_remap = program_gamut_remap,
|
||||
.program_gamut_remap = dcn10_program_gamut_remap,
|
||||
.init_hw = dcn10_init_hw,
|
||||
.init_pipes = dcn10_init_pipes,
|
||||
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
|
||||
@ -3158,18 +3218,18 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
||||
.optimize_bandwidth = dcn10_optimize_bandwidth,
|
||||
.reset_hw_ctx_wrap = dcn10_reset_hw_ctx_wrap,
|
||||
.enable_stream_timing = dcn10_enable_stream_timing,
|
||||
.set_drr = set_drr,
|
||||
.get_position = get_position,
|
||||
.set_static_screen_control = set_static_screen_control,
|
||||
.set_drr = dcn10_set_drr,
|
||||
.get_position = dcn10_get_position,
|
||||
.set_static_screen_control = dcn10_set_static_screen_control,
|
||||
.setup_stereo = dcn10_setup_stereo,
|
||||
.set_avmute = dce110_set_avmute,
|
||||
.log_hw_state = dcn10_log_hw_state,
|
||||
.get_hw_state = dcn10_get_hw_state,
|
||||
.clear_status_bits = dcn10_clear_status_bits,
|
||||
.wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect,
|
||||
.edp_backlight_control = hwss_edp_backlight_control,
|
||||
.edp_power_control = hwss_edp_power_control,
|
||||
.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
|
||||
.edp_backlight_control = dce110_edp_backlight_control,
|
||||
.edp_power_control = dce110_edp_power_control,
|
||||
.edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
|
||||
.set_cursor_position = dcn10_set_cursor_position,
|
||||
.set_cursor_attribute = dcn10_set_cursor_attribute,
|
||||
.set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level,
|
||||
@ -3179,6 +3239,16 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
||||
.setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt,
|
||||
.set_clock = dcn10_set_clock,
|
||||
.get_clock = dcn10_get_clock,
|
||||
.did_underflow_occur = dcn10_did_underflow_occur,
|
||||
.init_blank = NULL,
|
||||
.disable_vga = dcn10_disable_vga,
|
||||
.bios_golden_init = dcn10_bios_golden_init,
|
||||
.plane_atomic_disable = dcn10_plane_atomic_disable,
|
||||
.plane_atomic_power_down = dcn10_plane_atomic_power_down,
|
||||
.enable_power_gating_plane = dcn10_enable_power_gating_plane,
|
||||
.dpp_pg_control = dcn10_dpp_pg_control,
|
||||
.hubp_pg_control = dcn10_hubp_pg_control,
|
||||
.dsc_pg_control = NULL,
|
||||
};
|
||||
|
||||
|
||||
|
@ -582,7 +582,7 @@ static const struct hubbub_funcs hubbub2_funcs = {
|
||||
.get_dcc_compression_cap = hubbub2_get_dcc_compression_cap,
|
||||
.wm_read_state = hubbub2_wm_read_state,
|
||||
.get_dchub_ref_freq = hubbub2_get_dchub_ref_freq,
|
||||
.program_watermarks = hubbub2_program_watermarks,
|
||||
.program_watermarks = hubbub2_program_watermarks
|
||||
};
|
||||
|
||||
void hubbub2_construct(struct dcn20_hubbub *hubbub,
|
||||
|
@ -64,23 +64,7 @@
|
||||
#define FN(reg_name, field_name) \
|
||||
hws->shifts->field_name, hws->masks->field_name
|
||||
|
||||
static void bios_golden_init(struct dc *dc)
|
||||
{
|
||||
struct dc_bios *bp = dc->ctx->dc_bios;
|
||||
int i;
|
||||
|
||||
/* initialize dcn global */
|
||||
bp->funcs->enable_disp_power_gating(bp,
|
||||
CONTROLLER_ID_D0, ASIC_PIPE_INIT);
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
/* initialize dcn per pipe */
|
||||
bp->funcs->enable_disp_power_gating(bp,
|
||||
CONTROLLER_ID_D0 + i, ASIC_PIPE_DISABLE);
|
||||
}
|
||||
}
|
||||
|
||||
static void enable_power_gating_plane(
|
||||
static void dcn20_enable_power_gating_plane(
|
||||
struct dce_hwseq *hws,
|
||||
bool enable)
|
||||
{
|
||||
@ -184,7 +168,7 @@ void dcn20_display_init(struct dc *dc)
|
||||
REG_WRITE(AZALIA_CONTROLLER_CLOCK_GATING, 0x1);
|
||||
}
|
||||
|
||||
static void disable_vga(
|
||||
void dcn20_disable_vga(
|
||||
struct dce_hwseq *hws)
|
||||
{
|
||||
REG_WRITE(D1VGA_CONTROL, 0);
|
||||
@ -487,29 +471,6 @@ static void dcn20_hubp_pg_control(
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void dcn20_plane_atomic_power_down(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct dpp *dpp = pipe_ctx->plane_res.dpp;
|
||||
|
||||
DC_LOGGER_INIT(dc->ctx->logger);
|
||||
|
||||
if (REG(DC_IP_REQUEST_CNTL)) {
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0,
|
||||
IP_REQUEST_EN, 1);
|
||||
dcn20_dpp_pg_control(hws, dpp->inst, false);
|
||||
dcn20_hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, false);
|
||||
dpp->funcs->dpp_reset(dpp);
|
||||
REG_SET(DC_IP_REQUEST_CNTL, 0,
|
||||
IP_REQUEST_EN, 0);
|
||||
DC_LOG_DEBUG(
|
||||
"Power gated front end %d\n", pipe_ctx->pipe_idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* disable HW used by plane.
|
||||
* note: cannot disable until disconnect is complete
|
||||
*/
|
||||
@ -535,7 +496,9 @@ static void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
hubp->power_gated = true;
|
||||
dc->optimized_required = false; /* We're powering off, no need to optimize */
|
||||
|
||||
dcn20_plane_atomic_power_down(dc, pipe_ctx);
|
||||
dc->hwss.plane_atomic_power_down(dc,
|
||||
pipe_ctx->plane_res.dpp,
|
||||
pipe_ctx->plane_res.hubp);
|
||||
|
||||
pipe_ctx->stream = NULL;
|
||||
memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
|
||||
@ -559,204 +522,6 @@ void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
pipe_ctx->pipe_idx);
|
||||
}
|
||||
|
||||
static void dcn20_init_hw(struct dc *dc)
|
||||
{
|
||||
int i, j;
|
||||
struct abm *abm = dc->res_pool->abm;
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct dc_bios *dcb = dc->ctx->dc_bios;
|
||||
struct resource_pool *res_pool = dc->res_pool;
|
||||
struct dc_state *context = dc->current_state;
|
||||
|
||||
if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
|
||||
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
|
||||
|
||||
// Initialize the dccg
|
||||
if (res_pool->dccg->funcs->dccg_init)
|
||||
res_pool->dccg->funcs->dccg_init(res_pool->dccg);
|
||||
|
||||
//Enable ability to power gate / don't force power on permanently
|
||||
enable_power_gating_plane(dc->hwseq, true);
|
||||
|
||||
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
REG_WRITE(RBBMIF_TIMEOUT_DIS, 0xFFFFFFFF);
|
||||
REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF);
|
||||
|
||||
dcn20_dccg_init(hws);
|
||||
|
||||
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
|
||||
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
|
||||
REG_WRITE(REFCLK_CNTL, 0);
|
||||
} else {
|
||||
if (!dcb->funcs->is_accelerated_mode(dcb)) {
|
||||
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 (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
if (res_pool->dccg && 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 {
|
||||
// Not all ASICs have DCCG sw component
|
||||
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);
|
||||
disable_vga(dc->hwseq);
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
/* Power up AND update implementation according to the
|
||||
* required signal (which may be different from the
|
||||
* default signal on connector).
|
||||
*/
|
||||
struct dc_link *link = dc->links[i];
|
||||
|
||||
link->link_enc->funcs->hw_init(link->link_enc);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||
/* Power gate DSCs */
|
||||
for (i = 0; i < res_pool->res_cap->num_dsc; i++)
|
||||
dcn20_dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
|
||||
#endif
|
||||
|
||||
/* Blank pixel data with OPP DPG */
|
||||
for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
|
||||
struct timing_generator *tg = dc->res_pool->timing_generators[i];
|
||||
|
||||
if (tg->funcs->is_tg_enabled(tg)) {
|
||||
dcn20_init_blank(dc, tg);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < res_pool->timing_generator_count; i++) {
|
||||
struct timing_generator *tg = dc->res_pool->timing_generators[i];
|
||||
|
||||
if (tg->funcs->is_tg_enabled(tg))
|
||||
tg->funcs->lock(tg);
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->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 < dc->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 < dc->res_pool->pipe_count; i++) {
|
||||
struct timing_generator *tg = dc->res_pool->timing_generators[i];
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||
struct hubp *hubp = dc->res_pool->hubps[i];
|
||||
struct dpp *dpp = dc->res_pool->dpps[i];
|
||||
|
||||
pipe_ctx->stream_res.tg = tg;
|
||||
pipe_ctx->pipe_idx = i;
|
||||
|
||||
pipe_ctx->plane_res.hubp = hubp;
|
||||
pipe_ctx->plane_res.dpp = dpp;
|
||||
pipe_ctx->plane_res.mpcc_inst = dpp->inst;
|
||||
hubp->mpcc_id = dpp->inst;
|
||||
hubp->opp_id = OPP_ID_INVALID;
|
||||
hubp->power_gated = false;
|
||||
pipe_ctx->stream_res.opp = NULL;
|
||||
|
||||
hubp->funcs->hubp_init(hubp);
|
||||
|
||||
//dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
|
||||
//dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
|
||||
dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
|
||||
pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
|
||||
/*to do*/
|
||||
hwss1_plane_atomic_disconnect(dc, 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 < dc->res_pool->timing_generator_count; i++) {
|
||||
struct timing_generator *tg = dc->res_pool->timing_generators[i];
|
||||
|
||||
if (tg->funcs->is_tg_enabled(tg))
|
||||
tg->funcs->unlock(tg);
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
dc->hwss.disable_plane(dc, pipe_ctx);
|
||||
|
||||
pipe_ctx->stream_res.tg = NULL;
|
||||
pipe_ctx->plane_res.hubp = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
|
||||
struct timing_generator *tg = dc->res_pool->timing_generators[i];
|
||||
|
||||
tg->funcs->tg_init(tg);
|
||||
}
|
||||
|
||||
/* end of FPGA. Below if real ASIC */
|
||||
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
|
||||
return;
|
||||
|
||||
|
||||
for (i = 0; i < res_pool->audio_count; i++) {
|
||||
struct audio *audio = res_pool->audios[i];
|
||||
|
||||
audio->funcs->hw_init(audio);
|
||||
}
|
||||
|
||||
if (abm != NULL) {
|
||||
abm->funcs->init_backlight(abm);
|
||||
abm->funcs->abm_init(abm);
|
||||
}
|
||||
|
||||
if (dmcu != NULL)
|
||||
dmcu->funcs->dmcu_init(dmcu);
|
||||
|
||||
if (abm != NULL && dmcu != NULL)
|
||||
abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum dc_status dcn20_enable_stream_timing(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct dc_state *context,
|
||||
@ -1409,7 +1174,7 @@ static void dcn20_apply_ctx_for_surface(
|
||||
if (old_pipe_ctx->stream_res.tg == tg &&
|
||||
old_pipe_ctx->plane_res.hubp &&
|
||||
old_pipe_ctx->plane_res.hubp->opp_id != OPP_ID_INVALID)
|
||||
dcn20_disable_plane(dc, old_pipe_ctx);
|
||||
dc->hwss.disable_plane(dc, old_pipe_ctx);
|
||||
}
|
||||
|
||||
if ((!pipe_ctx->plane_state ||
|
||||
@ -2169,14 +1934,126 @@ static void dcn20_program_dmdata_engine(struct pipe_ctx *pipe_ctx)
|
||||
hubp->inst, mode);
|
||||
}
|
||||
|
||||
static void dcn20_fpga_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 (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
|
||||
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
|
||||
|
||||
// Initialize the dccg
|
||||
if (res_pool->dccg->funcs->dccg_init)
|
||||
res_pool->dccg->funcs->dccg_init(res_pool->dccg);
|
||||
|
||||
//Enable ability to power gate / don't force power on permanently
|
||||
dc->hwss.enable_power_gating_plane(hws, true);
|
||||
|
||||
// Specific to FPGA dccg and registers
|
||||
REG_WRITE(RBBMIF_TIMEOUT_DIS, 0xFFFFFFFF);
|
||||
REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF);
|
||||
|
||||
dcn20_dccg_init(hws);
|
||||
|
||||
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
|
||||
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
|
||||
REG_WRITE(REFCLK_CNTL, 0);
|
||||
//
|
||||
|
||||
|
||||
/* Blank pixel data with OPP DPG */
|
||||
for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
|
||||
struct timing_generator *tg = dc->res_pool->timing_generators[i];
|
||||
|
||||
if (tg->funcs->is_tg_enabled(tg))
|
||||
dcn20_init_blank(dc, tg);
|
||||
}
|
||||
|
||||
for (i = 0; i < res_pool->timing_generator_count; i++) {
|
||||
struct timing_generator *tg = dc->res_pool->timing_generators[i];
|
||||
|
||||
if (tg->funcs->is_tg_enabled(tg))
|
||||
tg->funcs->lock(tg);
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->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 < dc->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 < dc->res_pool->pipe_count; i++) {
|
||||
struct timing_generator *tg = dc->res_pool->timing_generators[i];
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||
struct hubp *hubp = dc->res_pool->hubps[i];
|
||||
struct dpp *dpp = dc->res_pool->dpps[i];
|
||||
|
||||
pipe_ctx->stream_res.tg = tg;
|
||||
pipe_ctx->pipe_idx = i;
|
||||
|
||||
pipe_ctx->plane_res.hubp = hubp;
|
||||
pipe_ctx->plane_res.dpp = dpp;
|
||||
pipe_ctx->plane_res.mpcc_inst = dpp->inst;
|
||||
hubp->mpcc_id = dpp->inst;
|
||||
hubp->opp_id = OPP_ID_INVALID;
|
||||
hubp->power_gated = false;
|
||||
pipe_ctx->stream_res.opp = NULL;
|
||||
|
||||
hubp->funcs->hubp_init(hubp);
|
||||
|
||||
//dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
|
||||
//dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
|
||||
dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
|
||||
pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
|
||||
/*to do*/
|
||||
hwss1_plane_atomic_disconnect(dc, 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 < dc->res_pool->timing_generator_count; i++) {
|
||||
struct timing_generator *tg = dc->res_pool->timing_generators[i];
|
||||
|
||||
if (tg->funcs->is_tg_enabled(tg))
|
||||
tg->funcs->unlock(tg);
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
dc->hwss.disable_plane(dc, pipe_ctx);
|
||||
|
||||
pipe_ctx->stream_res.tg = NULL;
|
||||
pipe_ctx->plane_res.hubp = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
|
||||
struct timing_generator *tg = dc->res_pool->timing_generators[i];
|
||||
|
||||
tg->funcs->tg_init(tg);
|
||||
}
|
||||
}
|
||||
|
||||
void dcn20_hw_sequencer_construct(struct dc *dc)
|
||||
{
|
||||
dcn10_hw_sequencer_construct(dc);
|
||||
dc->hwss.init_hw = dcn20_init_hw;
|
||||
dc->hwss.init_pipes = NULL;
|
||||
dc->hwss.unblank_stream = dcn20_unblank_stream;
|
||||
dc->hwss.update_plane_addr = dcn20_update_plane_addr;
|
||||
dc->hwss.disable_plane = dcn20_disable_plane,
|
||||
dc->hwss.enable_stream_timing = dcn20_enable_stream_timing;
|
||||
dc->hwss.program_triplebuffer = dcn20_program_tripleBuffer;
|
||||
dc->hwss.set_input_transfer_func = dcn20_set_input_transfer_func;
|
||||
@ -2204,5 +2081,19 @@ void dcn20_hw_sequencer_construct(struct dc *dc)
|
||||
dc->hwss.reset_hw_ctx_wrap = dcn20_reset_hw_ctx_wrap;
|
||||
dc->hwss.update_mpcc = dcn20_update_mpcc;
|
||||
dc->hwss.set_flip_control_gsl = dcn20_set_flip_control_gsl;
|
||||
dc->hwss.did_underflow_occur = dcn10_did_underflow_occur;
|
||||
dc->hwss.init_blank = dcn20_init_blank;
|
||||
dc->hwss.disable_plane = dcn20_disable_plane;
|
||||
dc->hwss.plane_atomic_disable = dcn20_plane_atomic_disable;
|
||||
dc->hwss.enable_power_gating_plane = dcn20_enable_power_gating_plane;
|
||||
dc->hwss.dpp_pg_control = dcn20_dpp_pg_control;
|
||||
dc->hwss.hubp_pg_control = dcn20_hubp_pg_control;
|
||||
dc->hwss.dsc_pg_control = dcn20_dsc_pg_control;
|
||||
dc->hwss.disable_vga = dcn20_disable_vga;
|
||||
|
||||
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
dc->hwss.init_hw = dcn20_fpga_init_hw;
|
||||
dc->hwss.init_pipes = NULL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -141,6 +141,10 @@ struct hubbub_funcs {
|
||||
struct dcn_watermark_set *watermarks,
|
||||
unsigned int refclk_mhz,
|
||||
bool safe_to_lower);
|
||||
|
||||
bool (*is_allow_self_refresh_enabled)(struct hubbub *hubbub);
|
||||
void (*allow_self_refresh_control)(struct hubbub *hubbub, bool allow);
|
||||
|
||||
};
|
||||
|
||||
struct hubbub {
|
||||
|
@ -78,6 +78,8 @@ struct stream_resource;
|
||||
struct dc_phy_addr_space_config;
|
||||
struct dc_virtual_addr_space_config;
|
||||
#endif
|
||||
struct hubp;
|
||||
struct dpp;
|
||||
|
||||
struct hw_sequencer_funcs {
|
||||
|
||||
@ -280,6 +282,36 @@ struct hw_sequencer_funcs {
|
||||
void (*setup_vupdate_interrupt)(struct pipe_ctx *pipe_ctx);
|
||||
bool (*did_underflow_occur)(struct dc *dc, struct pipe_ctx *pipe_ctx);
|
||||
|
||||
void (*init_blank)(struct dc *dc, struct timing_generator *tg);
|
||||
void (*disable_vga)(struct dce_hwseq *hws);
|
||||
void (*bios_golden_init)(struct dc *dc);
|
||||
void (*plane_atomic_power_down)(struct dc *dc,
|
||||
struct dpp *dpp,
|
||||
struct hubp *hubp);
|
||||
|
||||
void (*plane_atomic_disable)(
|
||||
struct dc *dc, struct pipe_ctx *pipe_ctx);
|
||||
|
||||
void (*enable_power_gating_plane)(
|
||||
struct dce_hwseq *hws,
|
||||
bool enable);
|
||||
|
||||
void (*dpp_pg_control)(
|
||||
struct dce_hwseq *hws,
|
||||
unsigned int dpp_inst,
|
||||
bool power_on);
|
||||
|
||||
void (*hubp_pg_control)(
|
||||
struct dce_hwseq *hws,
|
||||
unsigned int hubp_inst,
|
||||
bool power_on);
|
||||
|
||||
void (*dsc_pg_control)(
|
||||
struct dce_hwseq *hws,
|
||||
unsigned int dsc_inst,
|
||||
bool power_on);
|
||||
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
|
||||
void (*update_odm)(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx);
|
||||
void (*program_all_writeback_pipes_in_tree)(
|
||||
|
Loading…
Reference in New Issue
Block a user