{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
- switch (link_enc_inst) {
- case 0:
- REG_UPDATE(SYMCLKA_CLOCK_ENABLE,
- SYMCLKA_CLOCK_ENABLE, 1);
- if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKA_ROOT_GATE_DISABLE, 1);
- break;
- case 1:
- REG_UPDATE(SYMCLKB_CLOCK_ENABLE,
- SYMCLKB_CLOCK_ENABLE, 1);
- if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKB_ROOT_GATE_DISABLE, 1);
- break;
- case 2:
- REG_UPDATE(SYMCLKC_CLOCK_ENABLE,
- SYMCLKC_CLOCK_ENABLE, 1);
- if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKC_ROOT_GATE_DISABLE, 1);
- break;
- case 3:
- REG_UPDATE(SYMCLKD_CLOCK_ENABLE,
- SYMCLKD_CLOCK_ENABLE, 1);
- if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
- REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, SYMCLKD_ROOT_GATE_DISABLE, 1);
- break;
- }
-
switch (stream_enc_inst) {
case 0:
REG_UPDATE_2(SYMCLKA_CLOCK_ENABLE,
}
}
-/*get other front end connected to this backend*/
-static uint8_t dccg401_get_number_enabled_symclk_fe_connected_to_be(struct dccg *dccg, uint32_t link_enc_inst)
-{
- uint8_t num_enabled_symclk_fe = 0;
- uint32_t fe_clk_en[4] = {0}, be_clk_sel[4] = {0};
- struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
- uint8_t i;
-
- REG_GET_2(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_EN, &fe_clk_en[0],
- SYMCLKA_FE_SRC_SEL, &be_clk_sel[0]);
-
- REG_GET_2(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_EN, &fe_clk_en[1],
- SYMCLKB_FE_SRC_SEL, &be_clk_sel[1]);
-
- REG_GET_2(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_EN, &fe_clk_en[2],
- SYMCLKC_FE_SRC_SEL, &be_clk_sel[2]);
-
- REG_GET_2(SYMCLKD_CLOCK_ENABLE, SYMCLKD_FE_EN, &fe_clk_en[3],
- SYMCLKD_FE_SRC_SEL, &be_clk_sel[3]);
-
- for (i = 0; i < ARRAY_SIZE(fe_clk_en); i++) {
- if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst)
- num_enabled_symclk_fe++;
- }
-
- return num_enabled_symclk_fe;
-}
-
static void dccg401_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
{
- uint8_t num_enabled_symclk_fe = 0;
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
switch (stream_enc_inst) {
SYMCLKD_FE_SRC_SEL, 0);
break;
}
-
- /*check other enabled symclk fe connected to this be */
- num_enabled_symclk_fe = dccg401_get_number_enabled_symclk_fe_connected_to_be(dccg, link_enc_inst);
- /*only turn off backend clk if other front ends attached to this backend are all off,
- for mst, only turn off the backend if this is the last front end*/
- if (num_enabled_symclk_fe == 0) {
- switch (link_enc_inst) {
- case 0:
- REG_UPDATE(SYMCLKA_CLOCK_ENABLE,
- SYMCLKA_CLOCK_ENABLE, 0);
- break;
- case 1:
- REG_UPDATE(SYMCLKB_CLOCK_ENABLE,
- SYMCLKB_CLOCK_ENABLE, 0);
- break;
- case 2:
- REG_UPDATE(SYMCLKC_CLOCK_ENABLE,
- SYMCLKC_CLOCK_ENABLE, 0);
- break;
- case 3:
- REG_UPDATE(SYMCLKD_CLOCK_ENABLE,
- SYMCLKD_CLOCK_ENABLE, 0);
- break;
- }
- }
}
static const struct dccg_funcs dccg401_funcs = {
}
}
+static void disable_link_output_symclk_on_tx_off(struct dc_link *link, enum dp_link_encoding link_encoding)
+{
+ struct dc *dc = link->ctx->dc;
+ struct pipe_ctx *pipe_ctx = NULL;
+ uint8_t i;
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+ if (pipe_ctx->stream && pipe_ctx->stream->link == link && pipe_ctx->top_pipe == NULL) {
+ pipe_ctx->clock_source->funcs->program_pix_clk(
+ pipe_ctx->clock_source,
+ &pipe_ctx->stream_res.pix_clk_params,
+ link_encoding,
+ &pipe_ctx->pll_settings);
+ break;
+ }
+ }
+}
+
+void dcn401_disable_link_output(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal)
+{
+ struct dc *dc = link->ctx->dc;
+ const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+ struct dmcu *dmcu = dc->res_pool->dmcu;
+
+ if (signal == SIGNAL_TYPE_EDP &&
+ link->dc->hwss.edp_backlight_control &&
+ !link->skip_implict_edp_power_control)
+ link->dc->hwss.edp_backlight_control(link, false);
+ else if (dmcu != NULL && dmcu->funcs->lock_phy)
+ dmcu->funcs->lock_phy(dmcu);
+
+ if (dc_is_tmds_signal(signal) && link->phy_state.symclk_ref_cnts.otg > 0) {
+ disable_link_output_symclk_on_tx_off(link, DP_UNKNOWN_ENCODING);
+ link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
+ } else {
+ link_hwss->disable_link_output(link, link_res, signal);
+ link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+ }
+
+ if (signal == SIGNAL_TYPE_EDP &&
+ link->dc->hwss.edp_backlight_control &&
+ !link->skip_implict_edp_power_control)
+ link->dc->hwss.edp_power_control(link, false);
+ else if (dmcu != NULL && dmcu->funcs->lock_phy)
+ dmcu->funcs->unlock_phy(dmcu);
+
+ dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
+}
+
void dcn401_set_cursor_position(struct pipe_ctx *pipe_ctx)
{
struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;