|| dc_is_virtual_signal(pipe_ctx->stream->signal))
pipe_ctx->clock_source =
dc->res_pool->dp_clock_source;
+ else if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_FRL)
+ pipe_ctx->clock_source =
+ dc->res_pool->dp_clock_source;
else {
if (stream && stream->link && stream->link->link_enc)
pipe_ctx->clock_source = find_matching_pll(
#include "dcn30/dcn30_vpg.h"
#include "dcn30/dcn30_afmt.h"
#include "dcn30/dcn30_dio_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn30/dcn30_dio_link_encoder.h"
#include "dce/dce_clock_source.h"
#include "dce/dce_audio.h"
};
+#define hpo_frl_stream_encoder_reg_list(id)\
+[id] = {\
+ DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST(id)\
+}
+
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST(id, 6)
+
+
+static const struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[] = {
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(6),
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id)\
+[id] = {\
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST(id)\
+}
+
+static const struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[] = {
+ hpo_frl_link_encoder_reg_list(0),
+};
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
static const struct dce_panel_cntl_registers panel_cntl_regs[] = {
{ DCN_PANEL_CNTL_REG_LIST() }
};
.num_video_plane = 6,
.num_audio = 6,
.num_stream_encoder = 6,
+ .num_hpo_frl = 1,
.num_pll = 6,
.num_dwb = 1,
.num_ddc = 6,
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn30_hpo_frl_stream_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct afmt *afmt;
+ struct vpg *vpg;
+ int afmt_inst;
+ int vpg_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 6;
+ afmt_inst = 6;
+ } else {
+ return NULL;
+ }
+
+ /* allocate HPO stream encoder and create VPG sub-block */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn30_vpg_create(ctx, vpg_inst);
+ afmt = dcn30_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3,
+ ctx,
+ ctx->dc_bios,
+ eng_id,
+ vpg,
+ afmt,
+ &hpo_frl_stream_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_se_shift, &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+static struct hpo_frl_link_encoder *dcn30_hpo_frl_link_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3,
+ ctx,
+ eng_id-ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_le_shift,
+ &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
static struct dce_hwseq *dcn30_hwseq_create(struct dc_context *ctx)
{
struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq);
.read_dce_straps = read_dce_straps,
.create_audio = dcn30_create_audio,
.create_stream_encoder = dcn30_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn30_hpo_frl_stream_encoder_create,
.create_hwseq = dcn30_hwseq_create,
};
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+
+ if (pool->base.hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.hpo_frl_stream_enc[i]->afmt));
+ pool->base.hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < (unsigned int)pool->base.res_cap->num_dsc; i++) {
if (pool->base.dscs[i] != NULL)
dcn20_dsc_destroy(&pool->base.dscs[i]);
.destroy = dcn30_destroy_resource_pool,
.link_enc_create = dcn30_link_encoder_create,
.panel_cntl_create = dcn30_panel_cntl_create,
+ .hpo_frl_link_enc_create = dcn30_hpo_frl_link_encoder_create,
.validate_bandwidth = dcn30_validate_bandwidth,
.calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg,
.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
dc->caps.max_slave_rgb_planes = 2;
dc->caps.post_blend_color_processing = true;
dc->caps.force_dp_tps4_for_cp2520 = true;
+ dc->caps.hdmi_hpo = true;
+ dc->config.skip_frl_pretraining = true;
dc->caps.extended_aux_timeout_support = true;
dc->caps.dmcub_support = true;
.num_video_plane = 4,
.num_audio = 4,
.num_stream_encoder = 4,
+ .num_hpo_frl = 0,
.num_pll = 4,
.num_dwb = 1,
.num_ddc = 4,
#include "dcn30/dcn30_dio_stream_encoder.h"
#include "dcn30/dcn30_dwb.h"
#include "dcn30/dcn30_dpp.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
#include "dcn30/dcn30_hubbub.h"
#include "dcn30/dcn30_hubp.h"
#include "dcn30/dcn30_mmhubbub.h"
.num_video_plane = 5,
.num_audio = 5,
.num_stream_encoder = 5,
+ .num_hpo_frl = 1,
.num_dwb = 1,
.num_ddc = 5,
.num_vmid = 16,
return &enc1->base;
}
+#define hpo_frl_stream_encoder_reg_list(id)\
+ [id] = { DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST(id) }
+
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST(id, 5)
+
+static const struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[] = {
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(5),
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+static struct hpo_frl_stream_encoder *dcn302_hpo_frl_stream_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct vpg *vpg;
+ struct afmt *afmt;
+ int vpg_inst;
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 5;
+ afmt_inst = 5;
+ } else
+ return NULL;
+
+ /* allocate HPO stream encoder and create VPG sub-block */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn302_vpg_create(ctx, vpg_inst);
+ afmt = dcn302_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3, ctx, ctx->dc_bios, eng_id, vpg, afmt,
+ &hpo_frl_stream_enc_regs[eng_id-ENGINE_ID_HPO_0], &hpo_se_shift, &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+#define hpo_frl_link_encoder_reg_list(id)\
+ [id] = { DCN3_0_HPO_FRL_LINK_ENC_REG_LIST(id) }
+
+static const struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[] = {
+ hpo_frl_link_encoder_reg_list(0),
+};
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
+static struct hpo_frl_link_encoder *dcn302_hpo_frl_link_encoder_create(enum engine_id eng_id, struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3, ctx, eng_id-ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id-ENGINE_ID_HPO_0], &hpo_le_shift, &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
#define clk_src_regs(index, pllid)\
[index] = { CS_COMMON_REG_LIST_DCN3_02(index, pllid) }
.read_dce_straps = read_dce_straps,
.create_audio = dcn302_create_audio,
.create_stream_encoder = dcn302_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn302_hpo_frl_stream_encoder_create,
.create_hwseq = dcn302_hwseq_create,
};
}
}
+ for (i = 0; i < pool->hpo_frl_stream_enc_count; i++) {
+ if (pool->hpo_frl_stream_enc[i] != NULL) {
+ if (pool->hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->hpo_frl_stream_enc[i]->vpg));
+ pool->hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+
+ if (pool->hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->hpo_frl_stream_enc[i]->afmt));
+ pool->hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->hpo_frl_stream_enc[i]));
+ pool->hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < (unsigned int)pool->res_cap->num_dsc; i++) {
if (pool->dscs[i] != NULL)
dcn20_dsc_destroy(&pool->dscs[i]);
.destroy = dcn302_destroy_resource_pool,
.link_enc_create = dcn302_link_encoder_create,
.panel_cntl_create = dcn302_panel_cntl_create,
+ .hpo_frl_link_enc_create = dcn302_hpo_frl_link_encoder_create,
.validate_bandwidth = dcn30_validate_bandwidth,
.calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg,
.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
dc->caps.max_slave_rgb_planes = 2;
dc->caps.post_blend_color_processing = true;
dc->caps.force_dp_tps4_for_cp2520 = true;
+ dc->caps.hdmi_hpo = true;
+ dc->config.skip_frl_pretraining = true;
dc->caps.extended_aux_timeout_support = true;
dc->caps.dmcub_support = true;
dc->caps.max_v_total = (1 << 15) - 1;
#include "dcn30/dcn30_dio_stream_encoder.h"
#include "dcn30/dcn30_dpp.h"
#include "dcn30/dcn30_dwb.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
#include "dcn30/dcn30_hubbub.h"
#include "dcn30/dcn30_hubp.h"
#include "dcn30/dcn30_mmhubbub.h"
.num_video_plane = 2,
.num_audio = 2,
.num_stream_encoder = 2,
+ .num_hpo_frl = 1,
.num_dwb = 1,
.num_ddc = 2,
.num_vmid = 16,
return &enc1->base;
}
+#define hpo_frl_stream_encoder_reg_list(id)\
+ [id] = { DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST(id) }
+
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST(id, 2)
+
+static const struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[] = {
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(2),
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+static struct hpo_frl_stream_encoder *dcn303_hpo_frl_stream_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct vpg *vpg;
+ struct afmt *afmt;
+ int vpg_inst;
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 2;
+ afmt_inst = 2;
+ } else
+ return NULL;
+
+ /* allocate HPO stream encoder and create VPG sub-block */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn303_vpg_create(ctx, vpg_inst);
+ afmt = dcn303_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3, ctx, ctx->dc_bios, eng_id, vpg, afmt,
+ &hpo_frl_stream_enc_regs[eng_id-ENGINE_ID_HPO_0], &hpo_se_shift, &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+#define hpo_frl_link_encoder_reg_list(id)\
+ [id] = { DCN3_0_HPO_FRL_LINK_ENC_REG_LIST(id) }
+
+static const struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[] = {
+ hpo_frl_link_encoder_reg_list(0),
+};
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
+static struct hpo_frl_link_encoder *dcn303_hpo_frl_link_encoder_create(enum engine_id eng_id, struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3, ctx, eng_id-ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id-ENGINE_ID_HPO_0], &hpo_le_shift, &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
#define clk_src_regs(index, pllid)\
[index] = { CS_COMMON_REG_LIST_DCN3_03(index, pllid) }
.read_dce_straps = read_dce_straps,
.create_audio = dcn303_create_audio,
.create_stream_encoder = dcn303_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn303_hpo_frl_stream_encoder_create,
.create_hwseq = dcn303_hwseq_create,
};
}
}
+ for (i = 0; i < pool->hpo_frl_stream_enc_count; i++) {
+ if (pool->hpo_frl_stream_enc[i] != NULL) {
+ if (pool->hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->hpo_frl_stream_enc[i]->vpg));
+ pool->hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+
+ if (pool->hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->hpo_frl_stream_enc[i]->afmt));
+ pool->hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->hpo_frl_stream_enc[i]));
+ pool->hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < (unsigned int)pool->res_cap->num_dsc; i++) {
if (pool->dscs[i] != NULL)
dcn20_dsc_destroy(&pool->dscs[i]);
.destroy = dcn303_destroy_resource_pool,
.link_enc_create = dcn303_link_encoder_create,
.panel_cntl_create = dcn303_panel_cntl_create,
+ .hpo_frl_link_enc_create = dcn303_hpo_frl_link_encoder_create,
.validate_bandwidth = dcn30_validate_bandwidth,
.calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg,
.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
dc->caps.max_slave_rgb_planes = 1;
dc->caps.post_blend_color_processing = true;
dc->caps.force_dp_tps4_for_cp2520 = true;
+ dc->caps.hdmi_hpo = true;
+ dc->config.skip_frl_pretraining = true;
dc->caps.extended_aux_timeout_support = true;
dc->caps.dmcub_support = true;
dc->caps.max_v_total = (1 << 15) - 1;
#include "dcn30/dcn30_vpg.h"
#include "dcn30/dcn30_afmt.h"
#include "dcn30/dcn30_dio_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn31/dcn31_apg.h"
DPCS_DCN31_MASK_SH_LIST(_MASK)
};
+#define hpo_frl_stream_encoder_reg_list(id)\
+[id] = {\
+ DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST(id)\
+}
+
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST(id, 6)
+
+
+static const struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[] = {
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(6),
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id)\
+[id] = {\
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST(id)\
+}
+
+static const struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[] = {
+ hpo_frl_link_encoder_reg_list(0),
+};
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
#define hpo_dp_stream_encoder_reg_list(id)\
[id] = {\
DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\
.num_audio = 5,
.num_stream_encoder = 5,
.num_dig_link_enc = 5,
+ .num_hpo_frl = 1,
.num_hpo_dp_stream_encoder = 4,
.num_hpo_dp_link_encoder = 2,
.num_pll = 5,
}
},
.disable_z10 = true,
+ .max_frl_rate = HDMI_FRL_LINK_RATE_10GBPS,
.enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/
.dml_hostvm_override = DML_HOSTVM_OVERRIDE_FALSE,
.using_dml2 = false,
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct afmt *afmt;
+ struct vpg *vpg;
+ int afmt_inst;
+ int vpg_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 5;
+ afmt_inst = 5;
+ } else {
+ return NULL;
+ }
+
+ /* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3,
+ ctx,
+ ctx->dc_bios,
+ eng_id,
+ vpg,
+ afmt,
+ &hpo_frl_stream_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_se_shift, &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3,
+ ctx,
+ eng_id - ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_le_shift,
+ &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create(
enum engine_id eng_id,
struct dc_context *ctx)
.read_dce_straps = read_dce_straps,
.create_audio = dcn31_create_audio,
.create_stream_encoder = dcn31_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn31_hpo_frl_stream_encoder_create,
.create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
.create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
.create_hwseq = dcn31_hwseq_create,
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+
+ if (pool->base.hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.hpo_frl_stream_enc[i]->afmt));
+ pool->base.hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
if (pool->base.hpo_dp_stream_enc[i] != NULL) {
if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
.link_enc_create_minimal = dcn31_link_enc_create_minimal,
.link_encs_assign = link_enc_cfg_link_encs_assign,
.link_enc_unassign = link_enc_cfg_link_enc_unassign,
+ .hpo_frl_link_enc_create = dcn31_hpo_frl_link_encoder_create,
.panel_cntl_create = dcn31_panel_cntl_create,
.validate_bandwidth = dcn31_validate_bandwidth,
.calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
dc->caps.force_dp_tps4_for_cp2520 = true;
if (dc->config.forceHBR2CP2520)
dc->caps.force_dp_tps4_for_cp2520 = false;
+ dc->caps.hdmi_hpo = true;
+ dc->config.skip_frl_pretraining = true;
dc->caps.dp_hpo = true;
dc->caps.dp_hdmi21_pcon_support = true;
dc->caps.edp_dsc_support = true;
#include "dcn30/dcn30_afmt.h"
#include "dcn31/dcn31_dio_link_encoder.h"
#include "dcn314/dcn314_dio_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn31/dcn31_apg.h"
DPCS_DCN31_MASK_SH_LIST(_MASK)
};
+#define hpo_frl_stream_encoder_reg_list(id)\
+[id] = {\
+ DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST(id)\
+}
+
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST(id, 6)
+
+
+static const struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[] = {
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(6),
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id)\
+[id] = {\
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST(id)\
+}
+
+static const struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[] = {
+ hpo_frl_link_encoder_reg_list(0),
+};
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
#define hpo_dp_stream_encoder_reg_list(id)\
[id] = {\
DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\
.num_audio = 5,
.num_stream_encoder = 5,
.num_dig_link_enc = 5,
+ .num_hpo_frl = 1,
.num_hpo_dp_stream_encoder = 4,
.num_hpo_dp_link_encoder = 2,
.num_pll = 5,
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct afmt *afmt;
+ struct vpg *vpg;
+ int afmt_inst;
+ int vpg_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ //Maps to VPG INST 5, vpg_inst 5 reg offset padded to inst 9
+ vpg_inst = 9;
+ afmt_inst = 5;
+ } else {
+ return NULL;
+ }
+
+ /* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3,
+ ctx,
+ ctx->dc_bios,
+ eng_id,
+ vpg,
+ afmt,
+ &hpo_frl_stream_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_se_shift,
+ &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3,
+ ctx,
+ eng_id - ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_le_shift,
+ &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create(
enum engine_id eng_id,
struct dc_context *ctx)
.read_dce_straps = read_dce_straps,
.create_audio = dcn31_create_audio,
.create_stream_encoder = dcn314_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn31_hpo_frl_stream_encoder_create,
.create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
.create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
.create_hwseq = dcn314_hwseq_create,
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+
+ if (pool->base.hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.hpo_frl_stream_enc[i]->afmt));
+ pool->base.hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
if (pool->base.hpo_dp_stream_enc[i] != NULL) {
if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
.link_enc_create_minimal = dcn31_link_enc_create_minimal,
.link_encs_assign = link_enc_cfg_link_encs_assign,
.link_enc_unassign = link_enc_cfg_link_enc_unassign,
+ .hpo_frl_link_enc_create = dcn31_hpo_frl_link_encoder_create,
.panel_cntl_create = dcn31_panel_cntl_create,
.validate_bandwidth = dcn314_validate_bandwidth,
.calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
dc->caps.force_dp_tps4_for_cp2520 = true;
if (dc->config.forceHBR2CP2520)
dc->caps.force_dp_tps4_for_cp2520 = false;
+ dc->caps.hdmi_hpo = true;
dc->caps.dp_hpo = true;
dc->caps.dp_hdmi21_pcon_support = true;
dc->caps.edp_dsc_support = true;
#include "dcn30/dcn30_vpg.h"
#include "dcn30/dcn30_afmt.h"
#include "dcn30/dcn30_dio_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn31/dcn31_apg.h"
DPCS_DCN31_MASK_SH_LIST(_MASK)
};
+#define hpo_frl_stream_encoder_reg_list(id)\
+[id] = {\
+ DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST(id)\
+}
+
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST(id, 6)
+
+
+static const struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[] = {
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(6),
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id)\
+[id] = {\
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST(id)\
+}
+
+static const struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[] = {
+ hpo_frl_link_encoder_reg_list(0),
+};
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
#define hpo_dp_stream_encoder_reg_list(id)\
[id] = {\
DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\
.num_audio = 5,
.num_stream_encoder = 5,
.num_dig_link_enc = 5,
+ .num_hpo_frl = 1,
.num_hpo_dp_stream_encoder = 4,
.num_hpo_dp_link_encoder = 2,
.num_pll = 5,
.afmt = true,
}
},
+ .max_frl_rate = HDMI_FRL_LINK_RATE_12GBPS,
.psr_power_use_phy_fsm = 0,
.using_dml2 = false,
.min_disp_clk_khz = 100000,
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct afmt *afmt;
+ struct vpg *vpg;
+ int afmt_inst;
+ int vpg_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 5;
+ afmt_inst = 5;
+ } else {
+ return NULL;
+ }
+
+ /* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3,
+ ctx,
+ ctx->dc_bios,
+ eng_id,
+ vpg,
+ afmt,
+ &hpo_frl_stream_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_se_shift,
+ &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3,
+ ctx,
+ eng_id - ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_le_shift,
+ &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create(
enum engine_id eng_id,
struct dc_context *ctx)
.read_dce_straps = read_dce_straps,
.create_audio = dcn31_create_audio,
.create_stream_encoder = dcn315_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn31_hpo_frl_stream_encoder_create,
.create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
.create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
.create_hwseq = dcn31_hwseq_create,
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+
+ if (pool->base.hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.hpo_frl_stream_enc[i]->afmt));
+ pool->base.hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
if (pool->base.hpo_dp_stream_enc[i] != NULL) {
if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
.link_enc_create_minimal = dcn31_link_enc_create_minimal,
.link_encs_assign = link_enc_cfg_link_encs_assign,
.link_enc_unassign = link_enc_cfg_link_enc_unassign,
+ .hpo_frl_link_enc_create = dcn31_hpo_frl_link_encoder_create,
.panel_cntl_create = dcn31_panel_cntl_create,
.validate_bandwidth = dcn31_validate_bandwidth,
.calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
dc->caps.force_dp_tps4_for_cp2520 = true;
if (dc->config.forceHBR2CP2520)
dc->caps.force_dp_tps4_for_cp2520 = false;
+ dc->caps.hdmi_hpo = true;
+ dc->config.skip_frl_pretraining = true;
dc->caps.dp_hpo = true;
dc->caps.dp_hdmi21_pcon_support = true;
dc->caps.edp_dsc_support = true;
#include "dcn30/dcn30_vpg.h"
#include "dcn30/dcn30_afmt.h"
#include "dcn30/dcn30_dio_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn31/dcn31_apg.h"
DPCS_DCN31_MASK_SH_LIST(_MASK)
};
+#define hpo_frl_stream_encoder_reg_list(id)\
+[id] = {\
+ DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST(id)\
+}
+
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST(id, 6)
+
+
+static const struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[] = {
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(6),
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id)\
+[id] = {\
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST(id)\
+}
+
+static const struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[] = {
+ hpo_frl_link_encoder_reg_list(0),
+};
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
#define hpo_dp_stream_encoder_reg_list(id)\
.num_audio = 5,
.num_stream_encoder = 5,
.num_dig_link_enc = 5,
+ .num_hpo_frl = 1,
.num_hpo_dp_stream_encoder = 4,
.num_hpo_dp_link_encoder = 2,
.num_pll = 5,
.afmt = true,
}
},
+ .max_frl_rate = HDMI_FRL_LINK_RATE_10GBPS, /*same as dcn3.1 for now*/
.using_dml2 = false,
};
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct afmt *afmt;
+ struct vpg *vpg;
+ int afmt_inst;
+ int vpg_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 5;
+ afmt_inst = 5;
+ } else {
+ return NULL;
+ }
+
+ /* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3,
+ ctx,
+ ctx->dc_bios,
+ eng_id,
+ vpg,
+ afmt,
+ &hpo_frl_stream_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_se_shift,
+ &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3,
+ ctx,
+ eng_id - ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_le_shift,
+ &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create(
enum engine_id eng_id,
.read_dce_straps = read_dce_straps,
.create_audio = dcn31_create_audio,
.create_stream_encoder = dcn316_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn31_hpo_frl_stream_encoder_create,
.create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
.create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
.create_hwseq = dcn31_hwseq_create,
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+ if (pool->base.hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.hpo_frl_stream_enc[i]->afmt));
+ pool->base.hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
if (pool->base.hpo_dp_stream_enc[i] != NULL) {
if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
.link_enc_create_minimal = dcn31_link_enc_create_minimal,
.link_encs_assign = link_enc_cfg_link_encs_assign,
.link_enc_unassign = link_enc_cfg_link_enc_unassign,
+ .hpo_frl_link_enc_create = dcn31_hpo_frl_link_encoder_create,
.panel_cntl_create = dcn31_panel_cntl_create,
.validate_bandwidth = dcn31_validate_bandwidth,
.calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg,
dc->caps.force_dp_tps4_for_cp2520 = true;
if (dc->config.forceHBR2CP2520)
dc->caps.force_dp_tps4_for_cp2520 = false;
+ dc->caps.hdmi_hpo = true;
+ dc->config.skip_frl_pretraining = true;
dc->caps.dp_hpo = true;
dc->caps.dp_hdmi21_pcon_support = true;
dc->caps.edp_dsc_support = true;
#include "dcn30/dcn30_afmt.h"
#include "dcn30/dcn30_dio_stream_encoder.h"
#include "dcn32/dcn32_dio_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn32/dcn32_hpo_dp_link_encoder.h"
REG_STRUCT[id-1].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
+#define SRI_ARR_DME(reg_name, block, id, offset)\
+ REG_STRUCT[id - offset].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
#define SRI_ARR_ALPHABET(reg_name, block, index, id)\
REG_STRUCT[index].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
//DPCS_DCN31_MASK_SH_LIST(_MASK)
};
+#define hpo_frl_stream_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST_RI(id)
+
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST_RI(id, 6)
+
+
+static struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[2];
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST_RI(id)
+
+static struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[1];
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
#define hpo_dp_stream_encoder_reg_init(id)\
DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id)
.num_video_plane = 4,
.num_audio = 5,
.num_stream_encoder = 5,
+ .num_hpo_frl = 1,
.num_hpo_dp_stream_encoder = 4,
.num_hpo_dp_link_encoder = 2,
.num_pll = 5,
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn32_hpo_frl_stream_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct afmt *afmt;
+ struct vpg *vpg;
+ int afmt_inst;
+ int vpg_inst;
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_stream_enc_regs
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(6);
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 5;
+ afmt_inst = 5;
+ } else {
+ return NULL;
+ }
+
+ /* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn32_vpg_create(ctx, vpg_inst);
+ afmt = dcn32_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3,
+ ctx,
+ ctx->dc_bios,
+ eng_id,
+ vpg,
+ afmt,
+ &hpo_frl_stream_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_se_shift,
+ &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+static struct hpo_frl_link_encoder *dcn32_hpo_frl_link_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_link_enc_regs
+ hpo_frl_link_encoder_reg_list(0);
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3,
+ ctx,
+ eng_id - ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_le_shift,
+ &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
static struct hpo_dp_stream_encoder *dcn32_hpo_dp_stream_encoder_create(
enum engine_id eng_id,
struct dc_context *ctx)
.read_dce_straps = read_dce_straps,
.create_audio = dcn32_create_audio,
.create_stream_encoder = dcn32_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn32_hpo_frl_stream_encoder_create,
.create_hpo_dp_stream_encoder = dcn32_hpo_dp_stream_encoder_create,
.create_hpo_dp_link_encoder = dcn32_hpo_dp_link_encoder_create,
.create_hwseq = dcn32_hwseq_create,
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+
+ if (pool->base.hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.hpo_frl_stream_enc[i]->afmt));
+ pool->base.hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
if (pool->base.hpo_dp_stream_enc[i] != NULL) {
if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
.destroy = dcn32_destroy_resource_pool,
.link_enc_create = dcn32_link_encoder_create,
.link_enc_create_minimal = NULL,
+ .hpo_frl_link_enc_create = dcn32_hpo_frl_link_encoder_create,
.panel_cntl_create = dcn32_panel_cntl_create,
.validate_bandwidth = dcn32_validate_bandwidth,
.calculate_wm_and_dlg = dcn32_calculate_wm_and_dlg,
dc->caps.force_dp_tps4_for_cp2520 = true;
if (dc->config.forceHBR2CP2520)
dc->caps.force_dp_tps4_for_cp2520 = false;
+ dc->caps.hdmi_hpo = true;
+ dc->config.skip_frl_pretraining = true;
dc->caps.dp_hpo = true;
dc->caps.dp_hdmi21_pcon_support = true;
dc->caps.edp_dsc_support = true;
SRI_ARR(DC_HPD_TOGGLE_FILT_CNTL, HPD, id))
/* Link encoder */
-#define LE_DCN3_REG_LIST_RI(id) \
- SRI_ARR(DIG_BE_CNTL, DIG, id), SRI_ARR(DIG_BE_EN_CNTL, DIG, id), \
- SRI_ARR(TMDS_CTL_BITS, DIG, id), \
- SRI_ARR(TMDS_DCBALANCER_CONTROL, DIG, id), SRI_ARR(DP_CONFIG, DP, id), \
- SRI_ARR(DP_DPHY_CNTL, DP, id), SRI_ARR(DP_DPHY_PRBS_CNTL, DP, id), \
- SRI_ARR(DP_DPHY_SCRAM_CNTL, DP, id), SRI_ARR(DP_DPHY_SYM0, DP, id), \
- SRI_ARR(DP_DPHY_SYM1, DP, id), SRI_ARR(DP_DPHY_SYM2, DP, id), \
- SRI_ARR(DP_DPHY_TRAINING_PATTERN_SEL, DP, id), \
- SRI_ARR(DP_LINK_CNTL, DP, id), SRI_ARR(DP_LINK_FRAMING_CNTL, DP, id), \
- SRI_ARR(DP_MSE_SAT0, DP, id), SRI_ARR(DP_MSE_SAT1, DP, id), \
- SRI_ARR(DP_MSE_SAT2, DP, id), SRI_ARR(DP_MSE_SAT_UPDATE, DP, id), \
- SRI_ARR(DP_SEC_CNTL, DP, id), SRI_ARR(DP_VID_STREAM_CNTL, DP, id), \
- SRI_ARR(DP_DPHY_FAST_TRAINING, DP, id), SRI_ARR(DP_SEC_CNTL1, DP, id), \
- SRI_ARR(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
+#define LE_DCN3_REG_LIST_RI(id) \
+ SRI_ARR(DIG_BE_CNTL, DIG, id), \
+ SRI_ARR(DIG_BE_EN_CNTL, DIG, id), \
+ SRI_ARR(TMDS_CTL_BITS, DIG, id), \
+ SRI_ARR(TMDS_DCBALANCER_CONTROL, DIG, id), \
+ SRI_ARR(DP_CONFIG, DP, id), SRI_ARR(DP_DPHY_CNTL, DP, id), \
+ SRI_ARR(DP_DPHY_PRBS_CNTL, DP, id), \
+ SRI_ARR(DP_DPHY_SCRAM_CNTL, DP, id), \
+ SRI_ARR(DP_DPHY_SYM0, DP, id), SRI_ARR(DP_DPHY_SYM1, DP, id), \
+ SRI_ARR(DP_DPHY_SYM2, DP, id), \
+ SRI_ARR(DP_DPHY_TRAINING_PATTERN_SEL, DP, id), \
+ SRI_ARR(DP_LINK_CNTL, DP, id), \
+ SRI_ARR(DP_LINK_FRAMING_CNTL, DP, id), \
+ SRI_ARR(DP_MSE_SAT0, DP, id), SRI_ARR(DP_MSE_SAT1, DP, id), \
+ SRI_ARR(DP_MSE_SAT2, DP, id), \
+ SRI_ARR(DP_MSE_SAT_UPDATE, DP, id), \
+ SRI_ARR(DP_SEC_CNTL, DP, id), \
+ SRI_ARR(DP_VID_STREAM_CNTL, DP, id), \
+ SRI_ARR(DP_DPHY_FAST_TRAINING, DP, id), \
+ SRI_ARR(DP_SEC_CNTL1, DP, id), \
+ SRI_ARR(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
SRI_ARR(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id)
#define LE_DCN31_REG_LIST_RI(id) \
I2C_HW_ENGINE_COMMON_REG_LIST_RI(id), SR_ARR_I2C(DIO_MEM_PWR_CTRL, id), \
SR_ARR_I2C(DIO_MEM_PWR_STATUS, id)
+#define DCN3_0_HDMI_STREAM_ENC_REG_LIST_RI(id) \
+ SR_ARR(HDMI_STREAM_ENC_CLOCK_CONTROL, id), \
+ SR_ARR(HDMI_STREAM_ENC_INPUT_MUX_CONTROL, id), \
+ SR_ARR(HDMI_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL0, id), \
+ SR_ARR(HDMI_STREAM_ENC_CLOCK_RAMP_ADJUSTER_FIFO_STATUS_CONTROL2, id)
+
+#define DCN3_0_HDMI_TB_ENC_REG_LIST_RI(id) \
+ SR_ARR(HDMI_TB_ENC_CONTROL, id), SR_ARR(HDMI_TB_ENC_H_ACTIVE_BLANK, id), \
+ SR_ARR(HDMI_TB_ENC_HC_ACTIVE_BLANK, id), SR_ARR(HDMI_TB_ENC_MODE, id), \
+ SR_ARR(HDMI_TB_ENC_PACKET_CONTROL, id), \
+ SR_ARR(HDMI_TB_ENC_DB_CONTROL, id), \
+ SR_ARR(HDMI_TB_ENC_PIXEL_FORMAT, id), \
+ SR_ARR(HDMI_TB_ENC_VBI_PACKET_CONTROL1, id), \
+ SR_ARR(HDMI_TB_ENC_GC_CONTROL, id), \
+ SR_ARR(HDMI_TB_ENC_GENERIC_PACKET_CONTROL0, id), \
+ SR_ARR(HDMI_TB_ENC_GENERIC_PACKET_CONTROL1, id), \
+ SR_ARR(HDMI_TB_ENC_GENERIC_PACKET0_1_LINE, id), \
+ SR_ARR(HDMI_TB_ENC_GENERIC_PACKET2_3_LINE, id), \
+ SR_ARR(HDMI_TB_ENC_GENERIC_PACKET4_5_LINE, id), \
+ SR_ARR(HDMI_TB_ENC_GENERIC_PACKET6_7_LINE, id), \
+ SR_ARR(HDMI_TB_ENC_GENERIC_PACKET8_9_LINE, id), \
+ SR_ARR(HDMI_TB_ENC_GENERIC_PACKET10_11_LINE, id), \
+ SR_ARR(HDMI_TB_ENC_GENERIC_PACKET12_13_LINE, id), \
+ SR_ARR(HDMI_TB_ENC_GENERIC_PACKET14_LINE, id), \
+ SR_ARR(HDMI_TB_ENC_ACR_PACKET_CONTROL, id), \
+ SR_ARR(HDMI_TB_ENC_ACR_32_0, id), SR_ARR(HDMI_TB_ENC_ACR_32_1, id), \
+ SR_ARR(HDMI_TB_ENC_ACR_44_0, id), SR_ARR(HDMI_TB_ENC_ACR_44_1, id), \
+ SR_ARR(HDMI_TB_ENC_ACR_48_0, id), SR_ARR(HDMI_TB_ENC_ACR_48_1, id), \
+ SR_ARR(HDMI_TB_ENC_CRC_CNTL, id), \
+ SR_ARR(HDMI_TB_ENC_METADATA_PACKET_CONTROL, id)
+
+#define DCN3_0_HPO_STREAM_ENC_DME_REG_LIST_RI(id, offset) \
+ SRI_ARR_DME(DME_CONTROL, DME, id, offset)
+
+#define DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST_RI(id) \
+ DCN3_0_HDMI_STREAM_ENC_REG_LIST_RI(id), DCN3_0_HDMI_TB_ENC_REG_LIST_RI(id)
+
+#define DCN3_0_HPO_FRL_LINK_ENC_REG_LIST_RI(id) \
+ SR_ARR(HDMI_LINK_ENC_CLK_CTRL, id), \
+ SR_ARR(HDMI_LINK_ENC_CONTROL, id), \
+ SR_ARR(HDMI_FRL_ENC_CONFIG, id), \
+ SR_ARR(HDMI_FRL_ENC_CONFIG2, id),\
+ SR_ARR(HDMI_FRL_ENC_MEM_CTRL, id)
+
#endif /* _DCN32_RESOURCE_H_ */
#include "dcn30/dcn30_afmt.h"
#include "dcn30/dcn30_dio_stream_encoder.h"
#include "dcn32/dcn32_dio_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn32/dcn32_hpo_dp_link_encoder.h"
REG_STRUCT[id-1].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
+#define SRI_ARR_DME(reg_name, block, id, offset)\
+ REG_STRUCT[id - offset].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
#define SRI_ARR_ALPHABET(reg_name, block, index, id)\
REG_STRUCT[index].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
// DPCS_DCN31_MASK_SH_LIST(_MASK)
};
+#define hpo_frl_stream_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST_RI(id)
+
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST_RI(id, 6)
+
+static struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[2];
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST_RI(id)
+
+static struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[1];
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
#define hpo_dp_stream_encoder_reg_init(id)\
DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id)
.num_video_plane = 4,
.num_audio = 5,
.num_stream_encoder = 5,
+ .num_hpo_frl = 1,
.num_hpo_dp_stream_encoder = 4,
.num_hpo_dp_link_encoder = 2,
.num_pll = 5,
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn321_hpo_frl_stream_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct afmt *afmt;
+ struct vpg *vpg;
+ int afmt_inst;
+ int vpg_inst;
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_stream_enc_regs
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(6);
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 5;
+ afmt_inst = 5;
+ } else {
+ return NULL;
+ }
+
+ /* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn321_vpg_create(ctx, vpg_inst);
+ afmt = dcn321_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3,
+ ctx,
+ ctx->dc_bios,
+ eng_id,
+ vpg,
+ afmt,
+ &hpo_frl_stream_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_se_shift,
+ &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+static struct hpo_frl_link_encoder *dcn321_hpo_frl_link_encoder_create(enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_link_enc_regs
+ hpo_frl_link_encoder_reg_list(0);
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3,
+ ctx,
+ eng_id - ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_le_shift,
+ &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
static struct hpo_dp_stream_encoder *dcn321_hpo_dp_stream_encoder_create(
enum engine_id eng_id,
struct dc_context *ctx)
.read_dce_straps = read_dce_straps,
.create_audio = dcn321_create_audio,
.create_stream_encoder = dcn321_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn321_hpo_frl_stream_encoder_create,
.create_hpo_dp_stream_encoder = dcn321_hpo_dp_stream_encoder_create,
.create_hpo_dp_link_encoder = dcn321_hpo_dp_link_encoder_create,
.create_hwseq = dcn321_hwseq_create,
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+
+ if (pool->base.hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.hpo_frl_stream_enc[i]->afmt));
+ pool->base.hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
if (pool->base.hpo_dp_stream_enc[i] != NULL) {
if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
.destroy = dcn321_destroy_resource_pool,
.link_enc_create = dcn321_link_encoder_create,
.link_enc_create_minimal = NULL,
+ .hpo_frl_link_enc_create = dcn321_hpo_frl_link_encoder_create,
.panel_cntl_create = dcn32_panel_cntl_create,
.validate_bandwidth = dcn32_validate_bandwidth,
.calculate_wm_and_dlg = dcn32_calculate_wm_and_dlg,
dc->caps.max_slave_rgb_planes = 2;
dc->caps.post_blend_color_processing = true;
dc->caps.force_dp_tps4_for_cp2520 = true;
+ dc->caps.hdmi_hpo = true;
+ dc->config.skip_frl_pretraining = true;
dc->caps.dp_hpo = true;
dc->caps.dp_hdmi21_pcon_support = true;
dc->caps.edp_dsc_support = true;
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
dc->caps.color.mpc.ocsc = 1;
dc->caps.color.mpc.preblend = true;
+ /* HACK: Force FRL support until BIOS is ready. */
+ dc->config.force_hdmi21_frl_enc_enable = true;
/* Use pipe context based otg sync logic */
dc->config.use_pipe_ctx_sync_logic = true;
#include "dcn30/dcn30_afmt.h"
#include "dcn31/dcn31_dio_link_encoder.h"
#include "dcn35/dcn35_dio_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn32/dcn32_hpo_dp_link_encoder.h"
REG_STRUCT[id-1].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
+#define SRI_ARR_DME(reg_name, block, id, offset)\
+ REG_STRUCT[id - offset].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
#define SRI_ARR_ALPHABET(reg_name, block, index, id)\
REG_STRUCT[index].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
//DPCS_DCN31_MASK_SH_LIST(_MASK)
};
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST_RI(id, 6)
+
+#define hpo_frl_stream_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST_RI(id)
+
+static struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[2];
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST_RI(id)
+
+static struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[1];
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
#define hpo_dp_stream_encoder_reg_init(id)\
DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id)
.num_audio = 5,
.num_stream_encoder = 5,
.num_dig_link_enc = 5,
+ .num_hpo_frl = 1,
.num_hpo_dp_stream_encoder = 4,
.num_hpo_dp_link_encoder = 2,
.num_pll = 4,/*1 c10 edp, 3xc20 combo PHY*/
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct vpg *vpg;
+ struct afmt *afmt;
+ int vpg_inst;
+ int afmt_inst;
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_stream_enc_regs
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(6);
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 5;
+ afmt_inst = 5;
+ } else
+ return NULL;
+
+ /* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3, ctx, ctx->dc_bios,
+ eng_id, vpg, afmt,
+ &hpo_frl_stream_enc_regs[eng_id-ENGINE_ID_HPO_0],
+ &hpo_se_shift, &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_link_enc_regs
+ hpo_frl_link_encoder_reg_list(0);
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3, ctx, eng_id-ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id-ENGINE_ID_HPO_0],
+ &hpo_le_shift, &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create(
enum engine_id eng_id,
struct dc_context *ctx)
.read_dce_straps = read_dce_straps,
.create_audio = dcn31_create_audio,
.create_stream_encoder = dcn35_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn31_hpo_frl_stream_encoder_create,
.create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
.create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
.create_hwseq = dcn35_hwseq_create,
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+ if (pool->base.hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.hpo_frl_stream_enc[i]->afmt));
+ pool->base.hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
if (pool->base.hpo_dp_stream_enc[i] != NULL) {
if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
.link_enc_create_minimal = dcn31_link_enc_create_minimal,
.link_encs_assign = link_enc_cfg_link_encs_assign,
.link_enc_unassign = link_enc_cfg_link_enc_unassign,
+ .hpo_frl_link_enc_create = dcn31_hpo_frl_link_encoder_create,
.panel_cntl_create = dcn31_panel_cntl_create,
.validate_bandwidth = dcn35_validate_bandwidth,
.calculate_wm_and_dlg = NULL,
dc->caps.force_dp_tps4_for_cp2520 = true;
if (dc->config.forceHBR2CP2520)
dc->caps.force_dp_tps4_for_cp2520 = false;
+ dc->caps.hdmi_hpo = true;
+ dc->config.skip_frl_pretraining = true;
dc->caps.dp_hpo = true;
dc->caps.dp_hdmi21_pcon_support = true;
#include "dcn31/dcn31_dio_link_encoder.h"
#include "dcn35/dcn35_dio_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn32/dcn32_hpo_dp_link_encoder.h"
REG_STRUCT[id-1].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
+#define SRI_ARR_DME(reg_name, block, id, offset)\
+ REG_STRUCT[id - offset].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
#define SRI_ARR_ALPHABET(reg_name, block, index, id)\
REG_STRUCT[index].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
//DPCS_DCN31_MASK_SH_LIST(_MASK)
};
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST_RI(id, 6)
+
+#define hpo_frl_stream_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST_RI(id)
+
+static struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[2];
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST_RI(id)
+
+static struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[1];
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
#define hpo_dp_stream_encoder_reg_init(id)\
DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id)
.num_audio = 5,
.num_stream_encoder = 5,
.num_dig_link_enc = 5,
+ .num_hpo_frl = 1,
.num_hpo_dp_stream_encoder = 4,
.num_hpo_dp_link_encoder = 2,
.num_pll = 4,/*1 c10 edp, 3xc20 combo PHY*/
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct vpg *vpg;
+ struct afmt *afmt;
+ int vpg_inst;
+ int afmt_inst;
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_stream_enc_regs
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(6);
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 5;
+ afmt_inst = 5;
+ } else
+ return NULL;
+
+ /* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3, ctx, ctx->dc_bios,
+ eng_id, vpg, afmt,
+ &hpo_frl_stream_enc_regs[eng_id-ENGINE_ID_HPO_0],
+ &hpo_se_shift, &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_link_enc_regs
+ hpo_frl_link_encoder_reg_list(0);
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3, ctx, eng_id-ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id-ENGINE_ID_HPO_0],
+ &hpo_le_shift, &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create(
enum engine_id eng_id,
struct dc_context *ctx)
.read_dce_straps = read_dce_straps,
.create_audio = dcn31_create_audio,
.create_stream_encoder = dcn35_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn31_hpo_frl_stream_encoder_create,
.create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
.create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
.create_hwseq = dcn351_hwseq_create,
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+ if (pool->base.hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.hpo_frl_stream_enc[i]->afmt));
+ pool->base.hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
if (pool->base.hpo_dp_stream_enc[i] != NULL) {
if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
.link_enc_create_minimal = dcn31_link_enc_create_minimal,
.link_encs_assign = link_enc_cfg_link_encs_assign,
.link_enc_unassign = link_enc_cfg_link_enc_unassign,
+ .hpo_frl_link_enc_create = dcn31_hpo_frl_link_encoder_create,
.panel_cntl_create = dcn31_panel_cntl_create,
.validate_bandwidth = dcn351_validate_bandwidth,
.calculate_wm_and_dlg = NULL,
dc->caps.force_dp_tps4_for_cp2520 = true;
if (dc->config.forceHBR2CP2520)
dc->caps.force_dp_tps4_for_cp2520 = false;
+ dc->caps.hdmi_hpo = true;
+ dc->config.skip_frl_pretraining = true;
dc->caps.dp_hpo = true;
dc->caps.dp_hdmi21_pcon_support = true;
#include "dcn30/dcn30_afmt.h"
#include "dcn31/dcn31_dio_link_encoder.h"
#include "dcn35/dcn35_dio_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn32/dcn32_hpo_dp_link_encoder.h"
REG_STRUCT[id-1].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
+#define SRI_ARR_DME(reg_name, block, id, offset)\
+ REG_STRUCT[id - offset].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
#define SRI_ARR_ALPHABET(reg_name, block, index, id)\
REG_STRUCT[index].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
//DPCS_DCN31_MASK_SH_LIST(_MASK)
};
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST_RI(id, 6)
+
+#define hpo_frl_stream_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST_RI(id)
+
+static struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[2];
+
+static const struct dcn30_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN3_0_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST_RI(id)
+
+static struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[1];
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
#define hpo_dp_stream_encoder_reg_init(id)\
DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id)
.num_audio = 5,
.num_stream_encoder = 5,
.num_dig_link_enc = 5,
+ .num_hpo_frl = 1,
.num_hpo_dp_stream_encoder = 4,
.num_hpo_dp_link_encoder = 2,
.num_pll = 4,/*1 c10 edp, 3xc20 combo PHY*/
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_stream_encoder *hpo_enc3;
+ struct vpg *vpg;
+ struct afmt *afmt;
+ int vpg_inst;
+ int afmt_inst;
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_stream_enc_regs
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(6);
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 5;
+ afmt_inst = 5;
+ } else
+ return NULL;
+
+ /* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc3 || !vpg || !afmt) {
+ kfree(hpo_enc3);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn30_hpo_frl_stream_encoder_construct(hpo_enc3, ctx, ctx->dc_bios,
+ eng_id, vpg, afmt,
+ &hpo_frl_stream_enc_regs[eng_id-ENGINE_ID_HPO_0],
+ &hpo_se_shift, &hpo_se_mask);
+
+ return &hpo_enc3->base;
+}
+
+static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_enc3;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_link_enc_regs
+ hpo_frl_link_encoder_reg_list(0);
+
+ /* allocate HPO link encoder */
+ hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_enc3)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_enc3, ctx, eng_id-ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id-ENGINE_ID_HPO_0],
+ &hpo_le_shift, &hpo_le_mask);
+
+ return &hpo_enc3->base;
+}
+
static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create(
enum engine_id eng_id,
struct dc_context *ctx)
.read_dce_straps = read_dce_straps,
.create_audio = dcn31_create_audio,
.create_stream_encoder = dcn35_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn31_hpo_frl_stream_encoder_create,
.create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create,
.create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create,
.create_hwseq = dcn36_hwseq_create,
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+ if (pool->base.hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.hpo_frl_stream_enc[i]->afmt));
+ pool->base.hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+ kfree(DCN30_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
if (pool->base.hpo_dp_stream_enc[i] != NULL) {
if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
.link_enc_create_minimal = dcn31_link_enc_create_minimal,
.link_encs_assign = link_enc_cfg_link_encs_assign,
.link_enc_unassign = link_enc_cfg_link_enc_unassign,
+ .hpo_frl_link_enc_create = dcn31_hpo_frl_link_encoder_create,
.panel_cntl_create = dcn31_panel_cntl_create,
.validate_bandwidth = dcn35_validate_bandwidth,
.calculate_wm_and_dlg = NULL,
dc->caps.force_dp_tps4_for_cp2520 = true;
if (dc->config.forceHBR2CP2520)
dc->caps.force_dp_tps4_for_cp2520 = false;
+ dc->caps.hdmi_hpo = true;
+ dc->config.skip_frl_pretraining = true;
dc->caps.dp_hpo = true;
dc->caps.dp_hdmi21_pcon_support = true;
#include "dcn30/dcn30_afmt.h"
#include "dcn30/dcn30_dio_stream_encoder.h"
#include "dcn401/dcn401_dio_stream_encoder.h"
+#include "dcn401/dcn401_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn32/dcn32_hpo_dp_link_encoder.h"
REG_STRUCT[id-1].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
+#define SRI_ARR_DME(reg_name, block, id, offset)\
+ REG_STRUCT[id - offset].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
+ reg ## block ## id ## _ ## reg_name
+
#define SRI_ARR_ALPHABET(reg_name, block, index, id)\
REG_STRUCT[index].reg_name = BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
};
+#define hpo_frl_stream_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_STREAM_ENC_REG_LIST_RI(id)
+
+#define hpo_frl_stream_encoder_dme_reg_list(id)\
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST_RI(id, 4)
+
+static struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[2];
+
+static const struct dcn401_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN401_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn401_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN401_HPO_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id)\
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST_RI(id)
+
+static struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[1];
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)
+};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)
+};
+
#define hpo_dp_stream_encoder_reg_init(id)\
DCN3_1_HPO_DP_STREAM_ENC_REG_LIST_RI(id)
.num_video_plane = 4,
.num_audio = 4,
.num_stream_encoder = 4,
+ .num_hpo_frl = 1,
.num_hpo_dp_stream_encoder = 4,
.num_hpo_dp_link_encoder = 4,
.num_pll = 4,
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn401_hpo_frl_stream_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn401_hpo_frl_stream_encoder *hpo_enc401;
+ struct vpg *vpg;
+ struct afmt *afmt;
+ int vpg_inst;
+ int afmt_inst;
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_stream_enc_regs
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(4);
+
+ /* Mapping of VPG, AFMT, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 4;
+ afmt_inst = 4;
+ } else
+ return NULL;
+
+ /* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
+ hpo_enc401 = kzalloc(sizeof(struct dcn401_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn401_vpg_create(ctx, vpg_inst);
+ afmt = dcn401_afmt_create(ctx, afmt_inst);
+
+ if (!hpo_enc401 || !vpg || !afmt) {
+ kfree(hpo_enc401);
+ kfree(vpg);
+ kfree(afmt);
+ return NULL;
+ }
+
+ dcn401_hpo_frl_stream_encoder_construct(hpo_enc401, ctx, ctx->dc_bios,
+ eng_id, vpg, afmt,
+ &hpo_frl_stream_enc_regs[eng_id-ENGINE_ID_HPO_0],
+ &hpo_se_shift, &hpo_se_mask);
+
+ return &hpo_enc401->base;
+}
+
+static struct hpo_frl_link_encoder *dcn401_hpo_frl_link_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_link_enc;
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_link_enc_regs
+ hpo_frl_link_encoder_reg_list(0);
+
+ /* allocate HPO link encoder */
+ hpo_link_enc = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_link_enc)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_link_enc, ctx, eng_id-ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id-ENGINE_ID_HPO_0],
+ &hpo_le_shift, &hpo_le_mask);
+
+ return &hpo_link_enc->base;
+}
+
static struct hpo_dp_stream_encoder *dcn401_hpo_dp_stream_encoder_create(
enum engine_id eng_id,
struct dc_context *ctx)
.read_dce_straps = read_dce_straps,
.create_audio = dcn401_create_audio,
.create_stream_encoder = dcn401_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn401_hpo_frl_stream_encoder_create,
.create_hpo_dp_stream_encoder = dcn401_hpo_dp_stream_encoder_create,
.create_hpo_dp_link_encoder = dcn401_hpo_dp_link_encoder_create,
.create_hwseq = dcn401_hwseq_create,
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN31_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+ if (pool->base.hpo_frl_stream_enc[i]->afmt != NULL) {
+ kfree(DCN30_AFMT_FROM_AFMT(pool->base.hpo_frl_stream_enc[i]->afmt));
+ pool->base.hpo_frl_stream_enc[i]->afmt = NULL;
+ }
+ kfree(DCN401_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
if (pool->base.hpo_dp_stream_enc[i] != NULL) {
if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
.destroy = dcn401_destroy_resource_pool,
.link_enc_create = dcn401_link_encoder_create,
.link_enc_create_minimal = NULL,
+ .hpo_frl_link_enc_create = dcn401_hpo_frl_link_encoder_create,
.panel_cntl_create = dcn32_panel_cntl_create,
.validate_bandwidth = dcn401_validate_bandwidth,
.calculate_wm_and_dlg = NULL,
dc->caps.max_slave_rgb_planes = 3;
dc->caps.post_blend_color_processing = true;
dc->caps.force_dp_tps4_for_cp2520 = true;
+ dc->caps.hdmi_hpo = true;
dc->caps.dp_hpo = true;
dc->caps.dp_hdmi21_pcon_support = true;
dc->caps.edp_dsc_support = true;
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
dc->caps.color.mpc.ocsc = 1;
dc->caps.color.mpc.preblend = true;
+ /* HACK: Force FRL support until BIOS is ready. */
+ dc->config.force_hdmi21_frl_enc_enable = true;
dc->config.use_spl = true;
dc->config.prefer_easf = true;
#include "dcn31/dcn31_vpg.h"
#include "dcn42/dcn42_dio_stream_encoder.h"
#include "dcn42/dcn42_pg_cntl.h"
+#include "dcn401/dcn401_hpo_frl_stream_encoder.h"
+#include "dcn42/dcn42_hpo_frl_stream_encoder.h"
+#include "dcn30/dcn30_hpo_frl_link_encoder.h"
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
#include "dcn32/dcn32_hpo_dp_link_encoder.h"
REG_STRUCT[id - 1].reg_name = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
reg##block##id##_##reg_name
+#define SRI_ARR_DME(reg_name, block, id, offset) \
+ REG_STRUCT[id - offset].reg_name = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
+ reg##block##id##_##reg_name
#define SRI_ARR_ALPHABET(reg_name, block, index, id) \
REG_STRUCT[index].reg_name = BASE(reg##block##id##_##reg_name##_BASE_IDX) + \
static const struct dcn10_link_enc_mask le_mask = {
LINK_ENCODER_MASK_SH_LIST_DCN42(_MASK)};
+#define hpo_frl_stream_encoder_reg_list(id) \
+ DCN42_HPO_FRL_STREAM_ENC_REG_LIST_RI(id)
+
+#define hpo_frl_stream_encoder_dme_reg_list(id) \
+ DCN3_0_HPO_STREAM_ENC_DME_REG_LIST_RI(id, 6)
+
+static struct dcn30_hpo_frl_stream_enc_registers hpo_frl_stream_enc_regs[2];
+
+static const struct dcn401_hpo_frl_stream_encoder_shift hpo_se_shift = {
+ DCN401_HPO_STREAM_ENC_MASK_SH_LIST(__SHIFT),
+ DCN42_HDMI_STREAM_ENC_MASK_SH_LIST(__SHIFT)
+};
+static const struct dcn401_hpo_frl_stream_encoder_mask hpo_se_mask = {
+ DCN401_HPO_STREAM_ENC_MASK_SH_LIST(_MASK),
+ DCN42_HDMI_STREAM_ENC_MASK_SH_LIST(_MASK)
+};
+
+#define hpo_frl_link_encoder_reg_list(id) \
+ DCN3_0_HPO_FRL_LINK_ENC_REG_LIST_RI(id)
+
+static struct dcn30_hpo_frl_link_encoder_registers hpo_frl_link_enc_regs[1];
+
+static const struct dcn30_hpo_frl_link_encoder_shift hpo_le_shift = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(__SHIFT)};
+
+static const struct dcn30_hpo_frl_link_encoder_mask hpo_le_mask = {
+ DCN3_0_HPO_FRL_LINK_ENC_MASK_SH_LIST(_MASK)};
+
#define hpo_dp_stream_encoder_reg_init(id) \
DCN42_HPO_DP_STREAM_ENC_REG_LIST_RI(id)
.num_stream_encoder = 5,
.num_dig_link_enc = 5,
.num_usb4_dpia = 6,
+ .num_hpo_frl = 1,
.num_hpo_dp_stream_encoder = 4,
.num_hpo_dp_link_encoder = 4,
.num_pll = 5,
return &enc1->base;
}
+static struct hpo_frl_stream_encoder *dcn42_hpo_frl_stream_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn42_hpo_frl_stream_encoder *hpo_enc42;
+ struct vpg *vpg;
+ struct apg *apg;
+
+ uint32_t vpg_inst;
+ uint32_t apg_inst;
+
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_stream_enc_regs
+ hpo_frl_stream_encoder_reg_list(0),
+ hpo_frl_stream_encoder_dme_reg_list(6);
+
+ /* Mapping of VPG, DME register blocks to HPO block instance */
+ if (eng_id == ENGINE_ID_HPO_0) {
+ vpg_inst = 9; /*hw hard wired to inst 9, ref to dcn header file*/
+ apg_inst = 9;
+ } else
+ return NULL;
+
+ /* allocate HPO stream encoder and create VPG sub-block */
+ hpo_enc42 = kzalloc(sizeof(struct dcn42_hpo_frl_stream_encoder), GFP_KERNEL);
+ vpg = dcn42_vpg_create(ctx, vpg_inst);
+ apg = dcn42_apg_create(ctx, apg_inst);
+
+ if (!hpo_enc42 || !vpg || !apg) {
+ kfree(hpo_enc42);
+ kfree(vpg);
+ kfree(apg);
+ return NULL;
+ }
+
+ dcn42_hpo_frl_stream_encoder_construct(hpo_enc42, ctx, ctx->dc_bios,
+ eng_id, vpg, apg,
+ &hpo_frl_stream_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_se_shift, &hpo_se_mask);
+
+ return &hpo_enc42->base;
+}
+
+static struct hpo_frl_link_encoder *dcn42_hpo_frl_link_encoder_create(
+ enum engine_id eng_id,
+ struct dc_context *ctx)
+{
+ struct dcn30_hpo_frl_link_encoder *hpo_link_enc;
+
+ ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
+
+#undef REG_STRUCT
+#define REG_STRUCT hpo_frl_link_enc_regs
+ hpo_frl_link_encoder_reg_list(0);
+
+ /* allocate HPO link encoder */
+ hpo_link_enc = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ if (!hpo_link_enc)
+ return NULL; /* out of memory */
+
+ hpo_frl_link_encoder3_construct(hpo_link_enc, ctx, eng_id - ENGINE_ID_HPO_0,
+ &hpo_frl_link_enc_regs[eng_id - ENGINE_ID_HPO_0],
+ &hpo_le_shift, &hpo_le_mask);
+
+ return &hpo_link_enc->base;
+}
+
static struct hpo_dp_stream_encoder *dcn42_hpo_dp_stream_encoder_create(
enum engine_id eng_id,
struct dc_context *ctx)
.read_dce_straps = read_dce_straps,
.create_audio = dcn42_create_audio,
.create_stream_encoder = dcn42_stream_encoder_create,
+ .create_hpo_frl_stream_encoder = dcn42_hpo_frl_stream_encoder_create,
.create_hpo_dp_stream_encoder = dcn42_hpo_dp_stream_encoder_create,
.create_hpo_dp_link_encoder = dcn42_hpo_dp_link_encoder_create,
.create_hwseq = dcn42_hwseq_create,
}
}
+ for (i = 0; i < pool->base.hpo_frl_stream_enc_count; i++) {
+ if (pool->base.hpo_frl_stream_enc[i] != NULL) {
+ if (pool->base.hpo_frl_stream_enc[i]->vpg != NULL) {
+ kfree(DCN31_VPG_FROM_VPG(pool->base.hpo_frl_stream_enc[i]->vpg));
+ pool->base.hpo_frl_stream_enc[i]->vpg = NULL;
+ }
+ if (pool->base.hpo_frl_stream_enc[i]->apg != NULL) {
+ kfree(DCN31_APG_FROM_APG(pool->base.hpo_frl_stream_enc[i]->apg));
+ pool->base.hpo_frl_stream_enc[i]->apg = NULL;
+ }
+ kfree(DCN401_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(pool->base.hpo_frl_stream_enc[i]));
+ pool->base.hpo_frl_stream_enc[i] = NULL;
+ }
+ }
+
for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) {
if (pool->base.hpo_dp_stream_enc[i] != NULL) {
if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) {
.link_enc_create_minimal = dcn42_link_enc_create_minimal,
.link_encs_assign = link_enc_cfg_link_encs_assign,
.link_enc_unassign = link_enc_cfg_link_enc_unassign,
+ .hpo_frl_link_enc_create = dcn42_hpo_frl_link_encoder_create,
.panel_cntl_create = dcn32_panel_cntl_create,
.validate_bandwidth = dcn42_validate_bandwidth,
.calculate_wm_and_dlg = NULL,
dc->caps.force_dp_tps4_for_cp2520 = true;
if (dc->config.forceHBR2CP2520)
dc->caps.force_dp_tps4_for_cp2520 = false;
+ dc->caps.hdmi_hpo = true;
dc->caps.dp_hdmi21_pcon_support = true;
dc->caps.dp_hpo = true;
dc->caps.edp_dsc_support = true;