Merge tag 'drm-next-5.5-2019-11-01' of git://people.freedesktop.org/~agd5f/linux into drm-next

drm-next-5.5-2019-11-01:

amdgpu:
- Add EEPROM support for Arcturus
- Enable VCN encode support for Arcturus
- Misc PSP fixes
- Misc DC fixes
- swSMU cleanup

amdkfd:
- Misc cleanups
- Fix typo in cu bitmap parsing

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191101190607.3763-1-alexander.deucher@amd.com
This commit is contained in:
Dave Airlie
2019-11-04 10:22:53 +10:00
100 changed files with 3128 additions and 1150 deletions

View File

@@ -147,7 +147,7 @@ int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
/* Calculate the current DFS clock, in kHz.*/
dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->dentist_vco_freq_khz) / target_div;
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
return dce_adjust_dp_ref_freq_for_ss(clk_mgr, dp_ref_clk_khz);
}
@@ -239,7 +239,7 @@ int dce_set_clock(
/* Make sure requested clock isn't lower than minimum threshold*/
if (requested_clk_khz > 0)
requested_clk_khz = max(requested_clk_khz,
clk_mgr_dce->dentist_vco_freq_khz / 64);
clk_mgr_dce->base.dentist_vco_freq_khz / 64);
/* Prepare to program display clock*/
pxl_clk_params.target_pixel_clock_100hz = requested_clk_khz * 10;
@@ -276,11 +276,11 @@ static void dce_clock_read_integrated_info(struct clk_mgr_internal *clk_mgr_dce)
int i;
if (bp->integrated_info)
clk_mgr_dce->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq;
if (clk_mgr_dce->dentist_vco_freq_khz == 0) {
clk_mgr_dce->dentist_vco_freq_khz = bp->fw_info.smu_gpu_pll_output_freq;
if (clk_mgr_dce->dentist_vco_freq_khz == 0)
clk_mgr_dce->dentist_vco_freq_khz = 3600000;
clk_mgr_dce->base.dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq;
if (clk_mgr_dce->base.dentist_vco_freq_khz == 0) {
clk_mgr_dce->base.dentist_vco_freq_khz = bp->fw_info.smu_gpu_pll_output_freq;
if (clk_mgr_dce->base.dentist_vco_freq_khz == 0)
clk_mgr_dce->base.dentist_vco_freq_khz = 3600000;
}
/*update the maximum display clock for each power state*/

View File

@@ -81,7 +81,7 @@ int dce112_set_clock(struct clk_mgr *clk_mgr_base, int requested_clk_khz)
/* Make sure requested clock isn't lower than minimum threshold*/
if (requested_clk_khz > 0)
requested_clk_khz = max(requested_clk_khz,
clk_mgr_dce->dentist_vco_freq_khz / 62);
clk_mgr_dce->base.dentist_vco_freq_khz / 62);
dce_clk_params.target_clock_frequency = requested_clk_khz;
dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;
@@ -135,7 +135,7 @@ int dce112_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_clk_khz)
/* Make sure requested clock isn't lower than minimum threshold*/
if (requested_clk_khz > 0)
requested_clk_khz = max(requested_clk_khz,
clk_mgr->dentist_vco_freq_khz / 62);
clk_mgr->base.dentist_vco_freq_khz / 62);
dce_clk_params.target_clock_frequency = requested_clk_khz;
dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;

View File

@@ -269,11 +269,11 @@ void rv1_clk_mgr_construct(struct dc_context *ctx, struct clk_mgr_internal *clk_
clk_mgr->base.dprefclk_khz = 600000;
if (bp->integrated_info)
clk_mgr->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq;
if (bp->fw_info_valid && clk_mgr->dentist_vco_freq_khz == 0) {
clk_mgr->dentist_vco_freq_khz = bp->fw_info.smu_gpu_pll_output_freq;
if (clk_mgr->dentist_vco_freq_khz == 0)
clk_mgr->dentist_vco_freq_khz = 3600000;
clk_mgr->base.dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq;
if (bp->fw_info_valid && clk_mgr->base.dentist_vco_freq_khz == 0) {
clk_mgr->base.dentist_vco_freq_khz = bp->fw_info.smu_gpu_pll_output_freq;
if (clk_mgr->base.dentist_vco_freq_khz == 0)
clk_mgr->base.dentist_vco_freq_khz = 3600000;
}
if (!debug->disable_dfs_bypass && bp->integrated_info)

View File

@@ -108,11 +108,12 @@ void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
int dpp_inst, dppclk_khz;
if (!context->res_ctx.pipe_ctx[i].plane_state)
continue;
dpp_inst = context->res_ctx.pipe_ctx[i].plane_res.dpp->inst;
/* Loop index will match dpp->inst if resource exists,
* and we want to avoid dependency on dpp object
*/
dpp_inst = i;
dppclk_khz = context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;
clk_mgr->dccg->funcs->update_dpp_dto(
clk_mgr->dccg, dpp_inst, dppclk_khz);
}
@@ -121,9 +122,9 @@ void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr)
{
int dpp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->dentist_vco_freq_khz / clk_mgr->base.clks.dppclk_khz;
* clk_mgr->base.dentist_vco_freq_khz / clk_mgr->base.clks.dppclk_khz;
int disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->dentist_vco_freq_khz / clk_mgr->base.clks.dispclk_khz;
* clk_mgr->base.dentist_vco_freq_khz / clk_mgr->base.clks.dispclk_khz;
uint32_t dppclk_wdivider = dentist_get_did_from_divider(dpp_divider);
uint32_t dispclk_wdivider = dentist_get_did_from_divider(disp_divider);
@@ -235,6 +236,7 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
update_dispclk = true;
}
if (dc->config.forced_clocks == false || (force_reset && safe_to_lower)) {
if (dpp_clock_lowered) {
// if clock is being lowered, increase DTO before lowering refclk
@@ -244,10 +246,12 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
// if clock is being raised, increase refclk before lowering DTO
if (update_dppclk || update_dispclk)
dcn20_update_clocks_update_dentist(clk_mgr);
if (update_dppclk)
// always update dtos unless clock is lowered and not safe to lower
if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz)
dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
}
}
if (update_dispclk &&
dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) {
/*update dmcu for wait_loop count*/
@@ -260,6 +264,8 @@ void dcn2_update_clocks_fpga(struct clk_mgr *clk_mgr,
struct dc_state *context,
bool safe_to_lower)
{
struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr);
struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
/* Min fclk = 1.2GHz since all the extra scemi logic seems to run off of it */
int fclk_adj = new_clocks->fclk_khz > 1200000 ? new_clocks->fclk_khz : 1200000;
@@ -297,14 +303,18 @@ void dcn2_update_clocks_fpga(struct clk_mgr *clk_mgr,
clk_mgr->clks.dispclk_khz = new_clocks->dispclk_khz;
}
/* Both fclk and dppclk ref are run on the same scemi clock so we
* need to keep the same value for both
/* Both fclk and ref_dppclk run on the same scemi clock.
* So take the higher value since the DPP DTO is typically programmed
* such that max dppclk is 1:1 with ref_dppclk.
*/
if (clk_mgr->clks.fclk_khz > clk_mgr->clks.dppclk_khz)
clk_mgr->clks.dppclk_khz = clk_mgr->clks.fclk_khz;
if (clk_mgr->clks.dppclk_khz > clk_mgr->clks.fclk_khz)
clk_mgr->clks.fclk_khz = clk_mgr->clks.dppclk_khz;
// Both fclk and ref_dppclk run on the same scemi clock.
clk_mgr_int->dccg->ref_dppclk = clk_mgr->clks.fclk_khz;
dm_set_dcn_clocks(clk_mgr->ctx, &clk_mgr->clks);
}
@@ -406,7 +416,7 @@ void dcn20_clk_mgr_construct(
if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
dcn2_funcs.update_clocks = dcn2_update_clocks_fpga;
clk_mgr->dentist_vco_freq_khz = 3850000;
clk_mgr->base.dentist_vco_freq_khz = 3850000;
} else {
/* DFS Slice 2 should be used for DPREFCLK */
@@ -430,15 +440,15 @@ void dcn20_clk_mgr_construct(
pll_req = dc_fixpt_mul_int(pll_req, 100000);
/* integer part is now VCO frequency in kHz */
clk_mgr->dentist_vco_freq_khz = dc_fixpt_floor(pll_req);
clk_mgr->base.dentist_vco_freq_khz = dc_fixpt_floor(pll_req);
/* in case we don't get a value from the register, use default */
if (clk_mgr->dentist_vco_freq_khz == 0)
clk_mgr->dentist_vco_freq_khz = 3850000;
if (clk_mgr->base.dentist_vco_freq_khz == 0)
clk_mgr->base.dentist_vco_freq_khz = 3850000;
/* Calculate the DPREFCLK in kHz.*/
clk_mgr->base.dprefclk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
* clk_mgr->dentist_vco_freq_khz) / target_div;
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
}
//Integrated_info table does not exist on dGPU projects so should not be referenced
//anywhere in code for dGPUs.

View File

@@ -114,22 +114,22 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
*/
if (safe_to_lower) {
/* check that we're not already in lower */
if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_OPTIMIZED) {
if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) {
display_count = rn_get_active_display_cnt_wa(dc, context);
/* if we can go lower, go lower */
if (display_count == 0) {
rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_OPTIMIZED);
rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_LOW_POWER);
/* update power state */
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_OPTIMIZED;
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
}
}
} else {
/* check that we're not already in the normal state */
if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_NORMAL) {
rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_NORMAL);
/* check that we're not already in D0 */
if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_MISSION_MODE) {
rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_MISSION_MODE);
/* update power state */
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_NORMAL;
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_MISSION_MODE;
}
}
@@ -171,7 +171,8 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
// if clock is being raised, increase refclk before lowering DTO
if (update_dppclk || update_dispclk)
rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
if (update_dppclk)
// always update dtos unless clock is lowered and not safe to lower
if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz)
dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
}
@@ -393,7 +394,81 @@ void rn_init_clocks(struct clk_mgr *clk_mgr)
// Assumption is that boot state always supports pstate
clk_mgr->clks.p_state_change_support = true;
clk_mgr->clks.prev_p_state_change_support = true;
clk_mgr->clks.pwr_state = DCN_PWR_STATE_NORMAL;
clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN;
}
void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_range_sets *ranges)
{
int i, num_valid_sets;
num_valid_sets = 0;
for (i = 0; i < WM_SET_COUNT; i++) {
/* skip empty entries, the smu array has no holes*/
if (!bw_params->wm_table.entries[i].valid)
continue;
ranges->reader_wm_sets[num_valid_sets].wm_inst = bw_params->wm_table.entries[i].wm_inst;
ranges->reader_wm_sets[num_valid_sets].wm_type = bw_params->wm_table.entries[i].wm_type;;
/* We will not select WM based on dcfclk, so leave it as unconstrained */
ranges->reader_wm_sets[num_valid_sets].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->reader_wm_sets[num_valid_sets].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
/* fclk wil be used to select WM*/
if (ranges->reader_wm_sets[num_valid_sets].wm_type == WM_TYPE_PSTATE_CHG) {
if (i == 0)
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = 0;
else {
/* add 1 to make it non-overlapping with next lvl */
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = bw_params->clk_table.entries[i - 1].fclk_mhz + 1;
}
ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = bw_params->clk_table.entries[i].fclk_mhz;
} else {
/* unconstrained for memory retraining */
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
/* Modify previous watermark range to cover up to max */
ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
}
num_valid_sets++;
}
ASSERT(num_valid_sets != 0); /* Must have at least one set of valid watermarks */
ranges->num_reader_wm_sets = num_valid_sets;
/* modify the min and max to make sure we cover the whole range*/
ranges->reader_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->reader_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->reader_wm_sets[ranges->num_reader_wm_sets - 1].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
ranges->reader_wm_sets[ranges->num_reader_wm_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
/* This is for writeback only, does not matter currently as no writeback support*/
ranges->num_writer_wm_sets = 1;
ranges->writer_wm_sets[0].wm_inst = WM_A;
ranges->writer_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->writer_wm_sets[0].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
ranges->writer_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->writer_wm_sets[0].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
}
static void rn_notify_wm_ranges(struct clk_mgr *clk_mgr_base)
{
struct dc_debug_options *debug = &clk_mgr_base->ctx->dc->debug;
struct pp_smu_wm_range_sets ranges = {0};
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
struct pp_smu_funcs *pp_smu = clk_mgr->pp_smu;
if (!debug->disable_pplib_wm_range) {
build_watermark_ranges(clk_mgr_base->bw_params, &ranges);
/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
if (pp_smu && pp_smu->rn_funcs.set_wm_ranges)
pp_smu->rn_funcs.set_wm_ranges(&pp_smu->rn_funcs.pp_smu, &ranges);
}
}
static struct clk_mgr_funcs dcn21_funcs = {
@@ -401,7 +476,8 @@ static struct clk_mgr_funcs dcn21_funcs = {
.update_clocks = rn_update_clocks,
.init_clocks = rn_init_clocks,
.enable_pme_wa = rn_enable_pme_wa,
/* .dump_clk_registers = rn_dump_clk_registers */
/* .dump_clk_registers = rn_dump_clk_registers, */
.notify_wm_ranges = rn_notify_wm_ranges
};
struct clk_bw_params rn_bw_params = {
@@ -472,63 +548,6 @@ struct clk_bw_params rn_bw_params = {
}
};
void rn_build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_range_sets *ranges)
{
int i, num_valid_sets;
num_valid_sets = 0;
for (i = 0; i < WM_SET_COUNT; i++) {
/* skip empty entries, the smu array has no holes*/
if (!bw_params->wm_table.entries[i].valid)
continue;
ranges->reader_wm_sets[num_valid_sets].wm_inst = bw_params->wm_table.entries[i].wm_inst;
ranges->reader_wm_sets[num_valid_sets].wm_type = bw_params->wm_table.entries[i].wm_type;;
/* We will not select WM based on dcfclk, so leave it as unconstrained */
ranges->reader_wm_sets[num_valid_sets].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->reader_wm_sets[num_valid_sets].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
/* fclk wil be used to select WM*/
if (ranges->reader_wm_sets[num_valid_sets].wm_type == WM_TYPE_PSTATE_CHG) {
if (i == 0)
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = 0;
else {
/* add 1 to make it non-overlapping with next lvl */
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = bw_params->clk_table.entries[i - 1].fclk_mhz + 1;
}
ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = bw_params->clk_table.entries[i].fclk_mhz;
} else {
/* unconstrained for memory retraining */
ranges->reader_wm_sets[num_valid_sets].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
/* Modify previous watermark range to cover up to max */
ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
}
num_valid_sets++;
}
ASSERT(num_valid_sets != 0); /* Must have at least one set of valid watermarks */
ranges->num_reader_wm_sets = num_valid_sets;
/* modify the min and max to make sure we cover the whole range*/
ranges->reader_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->reader_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->reader_wm_sets[ranges->num_reader_wm_sets - 1].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
ranges->reader_wm_sets[ranges->num_reader_wm_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
/* This is for writeback only, does not matter currently as no writeback support*/
ranges->num_writer_wm_sets = 1;
ranges->writer_wm_sets[0].wm_inst = WM_A;
ranges->writer_wm_sets[0].min_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->writer_wm_sets[0].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
ranges->writer_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
ranges->writer_wm_sets[0].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
}
static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage)
{
int i;
@@ -542,7 +561,7 @@ static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsi
return 0;
}
void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id)
static void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id)
{
int i, j = 0;
@@ -628,17 +647,17 @@ void rn_clk_mgr_construct(
if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
dcn21_funcs.update_clocks = dcn2_update_clocks_fpga;
clk_mgr->dentist_vco_freq_khz = 3600000;
clk_mgr->base.dentist_vco_freq_khz = 3600000;
clk_mgr->base.dprefclk_khz = 600000;
} else {
struct clk_log_info log_info = {0};
/* TODO: Check we get what we expect during bringup */
clk_mgr->dentist_vco_freq_khz = get_vco_frequency_from_reg(clk_mgr);
clk_mgr->base.dentist_vco_freq_khz = get_vco_frequency_from_reg(clk_mgr);
/* in case we don't get a value from the register, use default */
if (clk_mgr->dentist_vco_freq_khz == 0)
clk_mgr->dentist_vco_freq_khz = 3600000;
if (clk_mgr->base.dentist_vco_freq_khz == 0)
clk_mgr->base.dentist_vco_freq_khz = 3600000;
rn_dump_clk_registers(&s, &clk_mgr->base, &log_info);
/* Convert dprefclk units from MHz to KHz */
@@ -661,21 +680,6 @@ void rn_clk_mgr_construct(
rn_clk_mgr_helper_populate_bw_params(clk_mgr->base.bw_params, &clock_table, &ctx->asic_id);
}
/*
* Notify SMU which set of WM should be selected for different ranges of fclk
* On Renoir there is a maximumum of 4 DF pstates supported, could be less
* depending on DDR speed and fused maximum fclk.
*/
if (!debug->disable_pplib_wm_range) {
struct pp_smu_wm_range_sets ranges = {0};
rn_build_watermark_ranges(clk_mgr->base.bw_params, &ranges);
/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
if (pp_smu && pp_smu->rn_funcs.set_wm_ranges)
pp_smu->rn_funcs.set_wm_ranges(&pp_smu->rn_funcs.pp_smu, &ranges);
}
if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->smu_ver >= 0x00371500) {
/* enable powerfeatures when displaycount goes to 0 */
rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(clk_mgr, !debug->disable_48mhz_pwrdwn);

View File

@@ -33,13 +33,6 @@ struct rn_clk_registers {
uint32_t CLK1_CLK0_CURRENT_CNT; /* DPREFCLK */
};
void rn_build_watermark_ranges(
struct clk_bw_params *bw_params,
struct pp_smu_wm_range_sets *ranges);
void rn_clk_mgr_helper_populate_bw_params(
struct clk_bw_params *bw_params,
struct dpm_clocks *clock_table,
struct hw_asic_id *asic_id);
void rn_clk_mgr_construct(struct dc_context *ctx,
struct clk_mgr_internal *clk_mgr,
struct pp_smu_funcs *pp_smu,

View File

@@ -170,7 +170,7 @@ void rn_vbios_smu_set_dcn_low_power_state(struct clk_mgr_internal *clk_mgr, enum
{
int disp_count;
if (state == DCN_PWR_STATE_OPTIMIZED)
if (state == DCN_PWR_STATE_LOW_POWER)
disp_count = 0;
else
disp_count = 1;

View File

@@ -194,7 +194,7 @@ static bool create_links(
}
}
if (!should_destory_link) {
if (dc->config.force_enum_edp || !should_destory_link) {
dc->links[dc->link_count] = link;
link->dc = dc;
++dc->link_count;
@@ -601,6 +601,10 @@ static bool construct(struct dc *dc,
#ifdef CONFIG_DRM_AMD_DC_DCN2_0
// Allocate memory for the vm_helper
dc->vm_helper = kzalloc(sizeof(struct vm_helper), GFP_KERNEL);
if (!dc->vm_helper) {
dm_error("%s: failed to create dc->vm_helper\n", __func__);
goto fail;
}
#endif
memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides));
@@ -1241,15 +1245,9 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
dc_enable_stereo(dc, context, dc_streams, context->stream_count);
if (!dc->optimize_seamless_boot)
/* pplib is notified if disp_num changed */
dc->hwss.optimize_bandwidth(dc, context);
for (i = 0; i < context->stream_count; i++)
context->streams[i]->mode_changed = false;
memset(&context->commit_hints, 0, sizeof(context->commit_hints));
dc_release_state(dc->current_state);
dc->current_state = context;

View File

@@ -2436,6 +2436,191 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool
return true;
}
bool dc_link_get_psr_state(const struct dc_link *link, uint32_t *psr_state)
{
struct dc *core_dc = link->ctx->dc;
struct dmcu *dmcu = core_dc->res_pool->dmcu;
if (dmcu != NULL && link->psr_feature_enabled)
dmcu->funcs->get_psr_state(dmcu, psr_state);
return true;
}
static inline enum physical_phy_id
transmitter_to_phy_id(enum transmitter transmitter_value)
{
switch (transmitter_value) {
case TRANSMITTER_UNIPHY_A:
return PHYLD_0;
case TRANSMITTER_UNIPHY_B:
return PHYLD_1;
case TRANSMITTER_UNIPHY_C:
return PHYLD_2;
case TRANSMITTER_UNIPHY_D:
return PHYLD_3;
case TRANSMITTER_UNIPHY_E:
return PHYLD_4;
case TRANSMITTER_UNIPHY_F:
return PHYLD_5;
case TRANSMITTER_NUTMEG_CRT:
return PHYLD_6;
case TRANSMITTER_TRAVIS_CRT:
return PHYLD_7;
case TRANSMITTER_TRAVIS_LCD:
return PHYLD_8;
case TRANSMITTER_UNIPHY_G:
return PHYLD_9;
case TRANSMITTER_COUNT:
return PHYLD_COUNT;
case TRANSMITTER_UNKNOWN:
return PHYLD_UNKNOWN;
default:
WARN_ONCE(1, "Unknown transmitter value %d\n",
transmitter_value);
return PHYLD_UNKNOWN;
}
}
bool dc_link_setup_psr(struct dc_link *link,
const struct dc_stream_state *stream, struct psr_config *psr_config,
struct psr_context *psr_context)
{
struct dc *core_dc;
struct dmcu *dmcu;
int i;
/* updateSinkPsrDpcdConfig*/
union dpcd_psr_configuration psr_configuration;
psr_context->controllerId = CONTROLLER_ID_UNDEFINED;
if (!link)
return false;
core_dc = link->ctx->dc;
dmcu = core_dc->res_pool->dmcu;
if (!dmcu)
return false;
memset(&psr_configuration, 0, sizeof(psr_configuration));
psr_configuration.bits.ENABLE = 1;
psr_configuration.bits.CRC_VERIFICATION = 1;
psr_configuration.bits.FRAME_CAPTURE_INDICATION =
psr_config->psr_frame_capture_indication_req;
/* Check for PSR v2*/
if (psr_config->psr_version == 0x2) {
/* For PSR v2 selective update.
* Indicates whether sink should start capturing
* immediately following active scan line,
* or starting with the 2nd active scan line.
*/
psr_configuration.bits.LINE_CAPTURE_INDICATION = 0;
/*For PSR v2, determines whether Sink should generate
* IRQ_HPD when CRC mismatch is detected.
*/
psr_configuration.bits.IRQ_HPD_WITH_CRC_ERROR = 1;
}
dm_helpers_dp_write_dpcd(
link->ctx,
link,
368,
&psr_configuration.raw,
sizeof(psr_configuration.raw));
psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel;
psr_context->transmitterId = link->link_enc->transmitter;
psr_context->engineId = link->link_enc->preferred_engine;
for (i = 0; i < MAX_PIPES; i++) {
if (core_dc->current_state->res_ctx.pipe_ctx[i].stream
== stream) {
/* dmcu -1 for all controller id values,
* therefore +1 here
*/
psr_context->controllerId =
core_dc->current_state->res_ctx.
pipe_ctx[i].stream_res.tg->inst + 1;
break;
}
}
/* Hardcoded for now. Can be Pcie or Uniphy (or Unknown)*/
psr_context->phyType = PHY_TYPE_UNIPHY;
/*PhyId is associated with the transmitter id*/
psr_context->smuPhyId =
transmitter_to_phy_id(link->link_enc->transmitter);
psr_context->crtcTimingVerticalTotal = stream->timing.v_total;
psr_context->vsyncRateHz = div64_u64(div64_u64((stream->
timing.pix_clk_100hz * 100),
stream->timing.v_total),
stream->timing.h_total);
psr_context->psrSupportedDisplayConfig = true;
psr_context->psrExitLinkTrainingRequired =
psr_config->psr_exit_link_training_required;
psr_context->sdpTransmitLineNumDeadline =
psr_config->psr_sdp_transmit_line_num_deadline;
psr_context->psrFrameCaptureIndicationReq =
psr_config->psr_frame_capture_indication_req;
psr_context->skipPsrWaitForPllLock = 0; /* only = 1 in KV */
psr_context->numberOfControllers =
link->dc->res_pool->timing_generator_count;
psr_context->rfb_update_auto_en = true;
/* 2 frames before enter PSR. */
psr_context->timehyst_frames = 2;
/* half a frame
* (units in 100 lines, i.e. a value of 1 represents 100 lines)
*/
psr_context->hyst_lines = stream->timing.v_total / 2 / 100;
psr_context->aux_repeats = 10;
psr_context->psr_level.u32all = 0;
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
/*skip power down the single pipe since it blocks the cstate*/
if (ASICREV_IS_RAVEN(link->ctx->asic_id.hw_internal_rev))
psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
#endif
/* SMU will perform additional powerdown sequence.
* For unsupported ASICs, set psr_level flag to skip PSR
* static screen notification to SMU.
* (Always set for DAL2, did not check ASIC)
*/
psr_context->allow_smu_optimizations = psr_config->allow_smu_optimizations;
/* Complete PSR entry before aborting to prevent intermittent
* freezes on certain eDPs
*/
psr_context->psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1;
/* Controls additional delay after remote frame capture before
* continuing power down, default = 0
*/
psr_context->frame_delay = 0;
link->psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context);
/* psr_enabled == 0 indicates setup_psr did not succeed, but this
* should not happen since firmware should be running at this point
*/
if (link->psr_feature_enabled == 0)
ASSERT(0);
return true;
}
const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
{
return &link->link_status;
@@ -2842,6 +3027,15 @@ void core_link_enable_stream(
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
COLOR_DEPTH_UNDEFINED);
/* This second call is needed to reconfigure the DIG
* as a workaround for the incorrect value being applied
* from transmitter control.
*/
if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
stream->link->link_enc->funcs->setup(
stream->link->link_enc,
pipe_ctx->stream->signal);
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
if (pipe_ctx->stream->timing.flags.DSC) {
if (dc_is_dp_signal(pipe_ctx->stream->signal) ||

View File

@@ -374,6 +374,7 @@ void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
enum display_dongle_type *dongle = &sink_cap->dongle_type;
uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE];
bool is_type2_dongle = false;
int retry_count = 2;
struct dp_hdmi_dongle_signature_data *dongle_signature;
/* Assume we have no valid DP passive dongle connected */
@@ -386,13 +387,24 @@ void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
DP_HDMI_DONGLE_ADDRESS,
type2_dongle_buf,
sizeof(type2_dongle_buf))) {
*dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
/* Passive HDMI dongles can sometimes fail here without retrying*/
while (retry_count > 0) {
if (i2c_read(ddc,
DP_HDMI_DONGLE_ADDRESS,
type2_dongle_buf,
sizeof(type2_dongle_buf)))
break;
retry_count--;
}
if (retry_count == 0) {
*dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
"DP-DVI passive dongle %dMhz: ",
DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
return;
CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
"DP-DVI passive dongle %dMhz: ",
DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
return;
}
}
/* Check if Type 2 dongle.*/

View File

@@ -404,6 +404,9 @@ bool resource_are_streams_timing_synchronizable(
if (stream1->view_format != stream2->view_format)
return false;
if (stream1->ignore_msa_timing_param || stream2->ignore_msa_timing_param)
return false;
return true;
}
static bool is_dp_and_hdmi_sharable(
@@ -948,7 +951,7 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx)
data->inits.v_c_bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
}
static bool are_rect_integer_multiples(struct rect src, struct rect dest)
static bool are_rects_integer_multiples(struct rect src, struct rect dest)
{
if (dest.width >= src.width && dest.width % src.width == 0 &&
dest.height >= src.height && dest.height % src.height == 0)
@@ -956,6 +959,38 @@ static bool are_rect_integer_multiples(struct rect src, struct rect dest)
return false;
}
static void calculate_integer_scaling(struct pipe_ctx *pipe_ctx)
{
if (!pipe_ctx->plane_state->scaling_quality.integer_scaling)
return;
//for Centered Mode
if (pipe_ctx->stream->dst.width == pipe_ctx->stream->src.width &&
pipe_ctx->stream->dst.height == pipe_ctx->stream->src.height) {
// calculate maximum # of replication of src onto addressable
unsigned int integer_multiple = min(
pipe_ctx->stream->timing.h_addressable / pipe_ctx->stream->src.width,
pipe_ctx->stream->timing.v_addressable / pipe_ctx->stream->src.height);
//scale dst
pipe_ctx->stream->dst.width = integer_multiple * pipe_ctx->stream->src.width;
pipe_ctx->stream->dst.height = integer_multiple * pipe_ctx->stream->src.height;
//center dst onto addressable
pipe_ctx->stream->dst.x = (pipe_ctx->stream->timing.h_addressable - pipe_ctx->stream->dst.width)/2;
pipe_ctx->stream->dst.y = (pipe_ctx->stream->timing.v_addressable - pipe_ctx->stream->dst.height)/2;
}
//disable taps if src & dst are integer ratio
if (are_rects_integer_multiples(pipe_ctx->stream->src, pipe_ctx->stream->dst)) {
pipe_ctx->plane_state->scaling_quality.v_taps = 1;
pipe_ctx->plane_state->scaling_quality.h_taps = 1;
pipe_ctx->plane_state->scaling_quality.v_taps_c = 1;
pipe_ctx->plane_state->scaling_quality.h_taps_c = 1;
}
}
bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
{
const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
@@ -969,6 +1004,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
pipe_ctx->plane_res.scl_data.format = convert_pixel_format_to_dalsurface(
pipe_ctx->plane_state->format);
calculate_integer_scaling(pipe_ctx);
calculate_scaling_ratios(pipe_ctx);
calculate_viewport(pipe_ctx);
@@ -999,13 +1036,6 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
if (res &&
plane_state->scaling_quality.integer_scaling &&
are_rect_integer_multiples(pipe_ctx->plane_res.scl_data.viewport,
pipe_ctx->plane_res.scl_data.recout)) {
pipe_ctx->plane_res.scl_data.taps.v_taps = 1;
pipe_ctx->plane_res.scl_data.taps.h_taps = 1;
}
if (!res) {
/* Try 24 bpp linebuffer */
@@ -1540,6 +1570,9 @@ bool dc_is_stream_unchanged(
if (!are_stream_backends_same(old_stream, stream))
return false;
if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param)
return false;
return true;
}
@@ -1629,7 +1662,8 @@ static int acquire_first_free_pipe(
static struct audio *find_first_free_audio(
struct resource_context *res_ctx,
const struct resource_pool *pool,
enum engine_id id)
enum engine_id id,
enum dce_version dc_version)
{
int i, available_audio_count;
@@ -1965,7 +1999,7 @@ enum dc_status resource_map_pool_resources(
dc_is_audio_capable_signal(pipe_ctx->stream->signal) &&
stream->audio_info.mode_count && stream->audio_info.flags.all) {
pipe_ctx->stream_res.audio = find_first_free_audio(
&context->res_ctx, pool, pipe_ctx->stream_res.stream_enc->id);
&context->res_ctx, pool, pipe_ctx->stream_res.stream_enc->id, dc_ctx->dce_version);
/*
* Audio assigned in order first come first get.

View File

@@ -39,7 +39,7 @@
#include "inc/hw/dmcu.h"
#include "dml/display_mode_lib.h"
#define DC_VER "3.2.54"
#define DC_VER "3.2.56"
#define MAX_SURFACES 3
#define MAX_PLANES 6
@@ -220,6 +220,7 @@ struct dc_config {
bool allow_seamless_boot_optimization;
bool power_down_display_on_boot;
bool edp_not_connected;
bool force_enum_edp;
bool forced_clocks;
bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well
bool multi_mon_pp_mclk_switch;
@@ -229,6 +230,7 @@ enum visual_confirm {
VISUAL_CONFIRM_DISABLE = 0,
VISUAL_CONFIRM_SURFACE = 1,
VISUAL_CONFIRM_HDR = 2,
VISUAL_CONFIRM_MPCTREE = 4,
};
enum dcc_option {
@@ -256,8 +258,9 @@ enum dtm_pstate{
};
enum dcn_pwr_state {
DCN_PWR_STATE_OPTIMIZED = 0,
DCN_PWR_STATE_NORMAL = 1
DCN_PWR_STATE_UNKNOWN = -1,
DCN_PWR_STATE_MISSION_MODE = 0,
DCN_PWR_STATE_LOW_POWER = 3,
};
/*

View File

@@ -49,7 +49,8 @@ enum aux_channel_operation_result {
AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN,
AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY,
AUX_CHANNEL_OPERATION_FAILED_TIMEOUT,
AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON
AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON,
AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE
};

View File

@@ -404,6 +404,10 @@ static bool dce_abm_init_backlight(struct abm *abm)
/* Enable the backlight output */
REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);
/* Disable fractional pwm if configured */
REG_UPDATE(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN,
abm->ctx->dc->config.disable_fractional_pwm ? 0 : 1);
/* Unlock group 2 backlight registers */
REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
BL_PWM_GRP1_REG_LOCK, 0);

View File

@@ -432,7 +432,6 @@ static bool dce_aux_configure_timeout(struct ddc_service *ddc,
{
uint32_t multiplier = 0;
uint32_t length = 0;
uint32_t timeout = 0;
struct ddc *ddc_pin = ddc->ddc_pin;
struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine);
@@ -446,25 +445,21 @@ static bool dce_aux_configure_timeout(struct ddc_service *ddc,
length = timeout_in_us/TIME_OUT_MULTIPLIER_8;
if (timeout_in_us % TIME_OUT_MULTIPLIER_8 != 0)
length++;
timeout = length * TIME_OUT_MULTIPLIER_8;
} else if (timeout_in_us <= 2 * TIME_OUT_INCREMENT) {
multiplier = 1;
length = timeout_in_us/TIME_OUT_MULTIPLIER_16;
if (timeout_in_us % TIME_OUT_MULTIPLIER_16 != 0)
length++;
timeout = length * TIME_OUT_MULTIPLIER_16;
} else if (timeout_in_us <= 4 * TIME_OUT_INCREMENT) {
multiplier = 2;
length = timeout_in_us/TIME_OUT_MULTIPLIER_32;
if (timeout_in_us % TIME_OUT_MULTIPLIER_32 != 0)
length++;
timeout = length * TIME_OUT_MULTIPLIER_32;
} else if (timeout_in_us > 4 * TIME_OUT_INCREMENT) {
multiplier = 3;
length = timeout_in_us/TIME_OUT_MULTIPLIER_64;
if (timeout_in_us % TIME_OUT_MULTIPLIER_64 != 0)
length++;
timeout = length * TIME_OUT_MULTIPLIER_64;
}
length = (length < MAX_TIMEOUT_LENGTH) ? length : MAX_TIMEOUT_LENGTH;
@@ -538,8 +533,10 @@ int dce_aux_transfer_raw(struct ddc_service *ddc,
memset(&aux_rep, 0, sizeof(aux_rep));
aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
if (!acquire(aux_engine, ddc_pin))
if (!acquire(aux_engine, ddc_pin)) {
*operation_result = AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE;
return -1;
}
if (payload->i2c_over_aux)
aux_req.type = AUX_TRANSACTION_TYPE_I2C;
@@ -663,6 +660,7 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
break;
case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON:
case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE:
case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN:
default:
goto fail;

View File

@@ -399,6 +399,37 @@ static const struct dc_plane_cap plane_cap = {
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
#endif
static int map_transmitter_id_to_phy_instance(
enum transmitter transmitter)
{
switch (transmitter) {
case TRANSMITTER_UNIPHY_A:
return 0;
break;
case TRANSMITTER_UNIPHY_B:
return 1;
break;
case TRANSMITTER_UNIPHY_C:
return 2;
break;
case TRANSMITTER_UNIPHY_D:
return 3;
break;
case TRANSMITTER_UNIPHY_E:
return 4;
break;
case TRANSMITTER_UNIPHY_F:
return 5;
break;
case TRANSMITTER_UNIPHY_G:
return 6;
break;
default:
ASSERT(0);
return 0;
}
}
static void read_dce_straps(
struct dc_context *ctx,
struct resource_straps *straps)
@@ -579,14 +610,18 @@ struct link_encoder *dce100_link_encoder_create(
{
struct dce110_link_encoder *enc110 =
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
int link_regs_id;
if (!enc110)
return NULL;
link_regs_id =
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
dce110_link_encoder_construct(enc110,
enc_init_data,
&link_enc_feature,
&link_enc_regs[enc_init_data->transmitter],
&link_enc_regs[link_regs_id],
&link_enc_aux_regs[enc_init_data->channel - 1],
&link_enc_hpd_regs[enc_init_data->hpd_source]);
return &enc110->base;

View File

@@ -1421,8 +1421,6 @@ static enum dc_status apply_single_controller_ctx_to_hw(
static void power_down_encoders(struct dc *dc)
{
int i;
enum connector_id connector_id;
enum signal_type signal = SIGNAL_TYPE_NONE;
/* do not know BIOS back-front mapping, simply blank all. It will not
* hurt for non-DP
@@ -1433,15 +1431,12 @@ static void power_down_encoders(struct dc *dc)
}
for (i = 0; i < dc->link_count; i++) {
connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id);
if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
(connector_id == CONNECTOR_ID_EDP)) {
enum signal_type signal = dc->links[i]->connector_signal;
if ((signal == SIGNAL_TYPE_EDP) ||
(signal == SIGNAL_TYPE_DISPLAY_PORT))
if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
dp_receiver_power_ctrl(dc->links[i], false);
if (connector_id == CONNECTOR_ID_EDP)
signal = SIGNAL_TYPE_EDP;
}
dc->links[i]->link_enc->funcs->disable_output(
dc->links[i]->link_enc, signal);

View File

@@ -448,6 +448,37 @@ static const struct dc_plane_cap underlay_plane_cap = {
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
#endif
static int map_transmitter_id_to_phy_instance(
enum transmitter transmitter)
{
switch (transmitter) {
case TRANSMITTER_UNIPHY_A:
return 0;
break;
case TRANSMITTER_UNIPHY_B:
return 1;
break;
case TRANSMITTER_UNIPHY_C:
return 2;
break;
case TRANSMITTER_UNIPHY_D:
return 3;
break;
case TRANSMITTER_UNIPHY_E:
return 4;
break;
case TRANSMITTER_UNIPHY_F:
return 5;
break;
case TRANSMITTER_UNIPHY_G:
return 6;
break;
default:
ASSERT(0);
return 0;
}
}
static void read_dce_straps(
struct dc_context *ctx,
struct resource_straps *straps)
@@ -625,14 +656,18 @@ static struct link_encoder *dce110_link_encoder_create(
{
struct dce110_link_encoder *enc110 =
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
int link_regs_id;
if (!enc110)
return NULL;
link_regs_id =
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
dce110_link_encoder_construct(enc110,
enc_init_data,
&link_enc_feature,
&link_enc_regs[enc_init_data->transmitter],
&link_enc_regs[link_regs_id],
&link_enc_aux_regs[enc_init_data->channel - 1],
&link_enc_hpd_regs[enc_init_data->hpd_source]);
return &enc110->base;

View File

@@ -425,6 +425,37 @@ static const struct dc_plane_cap plane_cap = {
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
#endif
static int map_transmitter_id_to_phy_instance(
enum transmitter transmitter)
{
switch (transmitter) {
case TRANSMITTER_UNIPHY_A:
return 0;
break;
case TRANSMITTER_UNIPHY_B:
return 1;
break;
case TRANSMITTER_UNIPHY_C:
return 2;
break;
case TRANSMITTER_UNIPHY_D:
return 3;
break;
case TRANSMITTER_UNIPHY_E:
return 4;
break;
case TRANSMITTER_UNIPHY_F:
return 5;
break;
case TRANSMITTER_UNIPHY_G:
return 6;
break;
default:
ASSERT(0);
return 0;
}
}
static void read_dce_straps(
struct dc_context *ctx,
struct resource_straps *straps)
@@ -583,14 +614,18 @@ struct link_encoder *dce112_link_encoder_create(
{
struct dce110_link_encoder *enc110 =
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
int link_regs_id;
if (!enc110)
return NULL;
link_regs_id =
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
dce110_link_encoder_construct(enc110,
enc_init_data,
&link_enc_feature,
&link_enc_regs[enc_init_data->transmitter],
&link_enc_regs[link_regs_id],
&link_enc_aux_regs[enc_init_data->channel - 1],
&link_enc_hpd_regs[enc_init_data->hpd_source]);
return &enc110->base;

View File

@@ -364,6 +364,37 @@ static const struct dce_audio_mask audio_mask = {
DCE120_AUD_COMMON_MASK_SH_LIST(_MASK)
};
static int map_transmitter_id_to_phy_instance(
enum transmitter transmitter)
{
switch (transmitter) {
case TRANSMITTER_UNIPHY_A:
return 0;
break;
case TRANSMITTER_UNIPHY_B:
return 1;
break;
case TRANSMITTER_UNIPHY_C:
return 2;
break;
case TRANSMITTER_UNIPHY_D:
return 3;
break;
case TRANSMITTER_UNIPHY_E:
return 4;
break;
case TRANSMITTER_UNIPHY_F:
return 5;
break;
case TRANSMITTER_UNIPHY_G:
return 6;
break;
default:
ASSERT(0);
return 0;
}
}
#define clk_src_regs(index, id)\
[index] = {\
CS_COMMON_REG_LIST_DCE_112(id),\
@@ -666,14 +697,18 @@ static struct link_encoder *dce120_link_encoder_create(
{
struct dce110_link_encoder *enc110 =
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
int link_regs_id;
if (!enc110)
return NULL;
link_regs_id =
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
dce110_link_encoder_construct(enc110,
enc_init_data,
&link_enc_feature,
&link_enc_regs[enc_init_data->transmitter],
&link_enc_regs[link_regs_id],
&link_enc_aux_regs[enc_init_data->channel - 1],
&link_enc_hpd_regs[enc_init_data->hpd_source]);

View File

@@ -439,6 +439,37 @@ static const struct dce_abm_mask abm_mask = {
#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
#endif
static int map_transmitter_id_to_phy_instance(
enum transmitter transmitter)
{
switch (transmitter) {
case TRANSMITTER_UNIPHY_A:
return 0;
break;
case TRANSMITTER_UNIPHY_B:
return 1;
break;
case TRANSMITTER_UNIPHY_C:
return 2;
break;
case TRANSMITTER_UNIPHY_D:
return 3;
break;
case TRANSMITTER_UNIPHY_E:
return 4;
break;
case TRANSMITTER_UNIPHY_F:
return 5;
break;
case TRANSMITTER_UNIPHY_G:
return 6;
break;
default:
ASSERT(0);
return 0;
}
}
static void read_dce_straps(
struct dc_context *ctx,
struct resource_straps *straps)
@@ -680,14 +711,18 @@ struct link_encoder *dce80_link_encoder_create(
{
struct dce110_link_encoder *enc110 =
kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
int link_regs_id;
if (!enc110)
return NULL;
link_regs_id =
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
dce110_link_encoder_construct(enc110,
enc_init_data,
&link_enc_feature,
&link_enc_regs[enc_init_data->transmitter],
&link_enc_regs[link_regs_id],
&link_enc_aux_regs[enc_init_data->channel - 1],
&link_enc_hpd_regs[enc_init_data->hpd_source]);
return &enc110->base;

View File

@@ -393,6 +393,10 @@ bool cm_helper_translate_curve_to_hw_format(
rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red;
rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green;
rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue;
// All 3 color channels have same x
corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2),
dc_fixpt_from_int(region_start));
@@ -464,13 +468,6 @@ bool cm_helper_translate_curve_to_hw_format(
i = 1;
while (i != hw_points + 1) {
if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
rgb_plus_1->red = rgb->red;
if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
rgb_plus_1->green = rgb->green;
if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
rgb_plus_1->blue = rgb->blue;
rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);
@@ -562,6 +559,10 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red;
rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green;
rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue;
corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2),
dc_fixpt_from_int(region_start));
corner_points[0].green.x = corner_points[0].red.x;
@@ -624,13 +625,6 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
i = 1;
while (i != hw_points + 1) {
if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
rgb_plus_1->red = rgb->red;
if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
rgb_plus_1->green = rgb->green;
if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
rgb_plus_1->blue = rgb->blue;
rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue);

View File

@@ -1304,6 +1304,10 @@ static void dcn10_init_hw(struct dc *dc)
}
dc->hwss.enable_power_gating_plane(dc->hwseq, true);
if (dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
}
static void dcn10_reset_hw_ctx_wrap(

View File

@@ -479,6 +479,28 @@ static const struct dcn_hubbub_mask hubbub_mask = {
HUBBUB_MASK_SH_LIST_DCN10(_MASK)
};
static int map_transmitter_id_to_phy_instance(
enum transmitter transmitter)
{
switch (transmitter) {
case TRANSMITTER_UNIPHY_A:
return 0;
break;
case TRANSMITTER_UNIPHY_B:
return 1;
break;
case TRANSMITTER_UNIPHY_C:
return 2;
break;
case TRANSMITTER_UNIPHY_D:
return 3;
break;
default:
ASSERT(0);
return 0;
}
}
#define clk_src_regs(index, pllid)\
[index] = {\
CS_COMMON_REG_LIST_DCN1_0(index, pllid),\
@@ -762,14 +784,18 @@ struct link_encoder *dcn10_link_encoder_create(
{
struct dcn10_link_encoder *enc10 =
kzalloc(sizeof(struct dcn10_link_encoder), GFP_KERNEL);
int link_regs_id;
if (!enc10)
return NULL;
link_regs_id =
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
dcn10_link_encoder_construct(enc10,
enc_init_data,
&link_enc_feature,
&link_enc_regs[enc_init_data->transmitter],
&link_enc_regs[link_regs_id],
&link_enc_aux_regs[enc_init_data->channel - 1],
&link_enc_hpd_regs[enc_init_data->hpd_source],
&le_shift,

View File

@@ -1202,15 +1202,9 @@ static void dcn20_update_dchubp_dpp(
struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
if (pipe_ctx->update_flags.bits.dppclk) {
if (pipe_ctx->update_flags.bits.dppclk)
dpp->funcs->dpp_dppclk_control(dpp, false, true);
dc->res_pool->dccg->funcs->update_dpp_dto(
dc->res_pool->dccg,
dpp->inst,
pipe_ctx->plane_res.bw.dppclk_khz);
}
/* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG
* VTG is within DCHUBBUB which is commond block share by each pipe HUBP.
* VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
@@ -1996,6 +1990,28 @@ static void dcn20_reset_hw_ctx_wrap(
}
}
void dcn20_get_mpctree_visual_confirm_color(
struct pipe_ctx *pipe_ctx,
struct tg_color *color)
{
const struct tg_color pipe_colors[6] = {
{MAX_TG_COLOR_VALUE, 0, 0}, // red
{MAX_TG_COLOR_VALUE, 0, MAX_TG_COLOR_VALUE}, // yellow
{0, MAX_TG_COLOR_VALUE, 0}, // blue
{MAX_TG_COLOR_VALUE / 2, 0, MAX_TG_COLOR_VALUE / 2}, // purple
{0, 0, MAX_TG_COLOR_VALUE}, // green
{MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE * 2 / 3, 0}, // orange
};
struct pipe_ctx *top_pipe = pipe_ctx;
while (top_pipe->top_pipe) {
top_pipe = top_pipe->top_pipe;
}
*color = pipe_colors[top_pipe->pipe_idx];
}
static void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
struct hubp *hubp = pipe_ctx->plane_res.hubp;
@@ -2013,6 +2029,9 @@ static void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {
dcn10_get_surface_visual_confirm_color(
pipe_ctx, &blnd_cfg.black_color);
} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_MPCTREE) {
dcn20_get_mpctree_visual_confirm_color(
pipe_ctx, &blnd_cfg.black_color);
}
if (per_pixel_alpha)

View File

@@ -109,5 +109,7 @@ bool dcn20_set_blend_lut(
struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
bool dcn20_set_shaper_3dlut(
struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
void dcn20_get_mpctree_visual_confirm_color(
struct pipe_ctx *pipe_ctx,
struct tg_color *color);
#endif /* __DC_HWSS_DCN20_H__ */

View File

@@ -742,6 +742,33 @@ static const struct dce110_aux_registers_mask aux_mask = {
DCN_AUX_MASK_SH_LIST(_MASK)
};
static int map_transmitter_id_to_phy_instance(
enum transmitter transmitter)
{
switch (transmitter) {
case TRANSMITTER_UNIPHY_A:
return 0;
break;
case TRANSMITTER_UNIPHY_B:
return 1;
break;
case TRANSMITTER_UNIPHY_C:
return 2;
break;
case TRANSMITTER_UNIPHY_D:
return 3;
break;
case TRANSMITTER_UNIPHY_E:
return 4;
break;
case TRANSMITTER_UNIPHY_F:
return 5;
break;
default:
ASSERT(0);
return 0;
}
}
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
#define dsc_regsDCN20(id)\
@@ -825,7 +852,7 @@ static const struct resource_caps res_cap_nv14 = {
.num_audio = 6,
.num_stream_encoder = 5,
.num_pll = 5,
.num_dwb = 0,
.num_dwb = 1,
.num_ddc = 5,
};
@@ -836,7 +863,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.clock_trace = true,
.disable_pplib_clock_request = true,
.pipe_split_policy = MPC_SPLIT_DYNAMIC,
.force_single_disp_pipe_split = true,
.force_single_disp_pipe_split = false,
.disable_dcc = DCC_ENABLE,
.vsr_support = true,
.performance_trace = false,
@@ -1056,14 +1083,18 @@ struct link_encoder *dcn20_link_encoder_create(
{
struct dcn20_link_encoder *enc20 =
kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
int link_regs_id;
if (!enc20)
return NULL;
link_regs_id =
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
dcn20_link_encoder_construct(enc20,
enc_init_data,
&link_enc_feature,
&link_enc_regs[enc_init_data->transmitter],
&link_enc_regs[link_regs_id],
&link_enc_aux_regs[enc_init_data->channel - 1],
&link_enc_hpd_regs[enc_init_data->hpd_source],
&le_shift,
@@ -1612,7 +1643,7 @@ static void swizzle_to_dml_params(
}
}
static bool dcn20_split_stream_for_odm(
bool dcn20_split_stream_for_odm(
struct resource_context *res_ctx,
const struct resource_pool *pool,
struct pipe_ctx *prev_odm_pipe,
@@ -1633,7 +1664,6 @@ static bool dcn20_split_stream_for_odm(
next_odm_pipe->stream_res.dsc = NULL;
#endif
if (prev_odm_pipe->next_odm_pipe && prev_odm_pipe->next_odm_pipe != next_odm_pipe) {
ASSERT(!next_odm_pipe->next_odm_pipe);
next_odm_pipe->next_odm_pipe = prev_odm_pipe->next_odm_pipe;
next_odm_pipe->next_odm_pipe->prev_odm_pipe = next_odm_pipe;
}
@@ -1690,7 +1720,7 @@ static bool dcn20_split_stream_for_odm(
return true;
}
static void dcn20_split_stream_for_mpc(
void dcn20_split_stream_for_mpc(
struct resource_context *res_ctx,
const struct resource_pool *pool,
struct pipe_ctx *primary_pipe,
@@ -2148,7 +2178,7 @@ void dcn20_set_mcif_arb_params(
}
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
{
int i;
@@ -2183,7 +2213,7 @@ static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
}
#endif
static struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
struct resource_context *res_ctx,
const struct resource_pool *pool,
const struct pipe_ctx *primary_pipe)
@@ -2260,25 +2290,11 @@ static struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
return secondary_pipe;
}
bool dcn20_fast_validate_bw(
void dcn20_merge_pipes_for_validate(
struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int *pipe_cnt_out,
int *pipe_split_from,
int *vlevel_out)
struct dc_state *context)
{
bool out = false;
int pipe_cnt, i, pipe_idx, vlevel, vlevel_unsplit;
bool force_split = false;
int split_threshold = dc->res_pool->pipe_count / 2;
bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC;
ASSERT(pipes);
if (!pipes)
return false;
int i;
/* merge previously split odm pipes since mode support needs to make the decision */
for (i = 0; i < dc->res_pool->pipe_count; i++) {
@@ -2333,35 +2349,19 @@ bool dcn20_fast_validate_bw(
if (pipe->plane_state)
resource_build_scaling_params(pipe);
}
}
if (dc->res_pool->funcs->populate_dml_pipes)
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
&context->res_ctx, pipes);
else
pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
&context->res_ctx, pipes);
int dcn20_validate_apply_pipe_split_flags(
struct dc *dc,
struct dc_state *context,
int vlevel,
bool *split)
{
int i, pipe_idx, vlevel_split;
bool force_split = false;
bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC;
*pipe_cnt_out = pipe_cnt;
if (!pipe_cnt) {
out = true;
goto validate_out;
}
vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
if (vlevel > context->bw_ctx.dml.soc.num_states)
goto validate_fail;
if ((context->stream_count > split_threshold && dc->current_state->stream_count <= split_threshold)
|| (context->stream_count <= split_threshold && dc->current_state->stream_count > split_threshold))
context->commit_hints.full_update_needed = true;
/*initialize pipe_just_split_from to invalid idx*/
for (i = 0; i < MAX_PIPES; i++)
pipe_split_from[i] = -1;
/* Single display only conditionals get set here */
/* Single display loop, exits if there is more than one display */
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
bool exit_loop = false;
@@ -2388,38 +2388,107 @@ bool dcn20_fast_validate_bw(
if (exit_loop)
break;
}
if (context->stream_count > split_threshold)
/* TODO: fix dc bugs and remove this split threshold thing */
if (context->stream_count > dc->res_pool->pipe_count / 2)
avoid_split = true;
vlevel_unsplit = vlevel;
/* Avoid split loop looks for lowest voltage level that allows most unsplit pipes possible */
if (avoid_split) {
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
if (!context->res_ctx.pipe_ctx[i].stream)
continue;
for (vlevel_split = vlevel; vlevel <= context->bw_ctx.dml.soc.num_states; vlevel++)
if (context->bw_ctx.dml.vba.NoOfDPP[vlevel][0][pipe_idx] == 1)
break;
/* Impossible to not split this pipe */
if (vlevel > context->bw_ctx.dml.soc.num_states)
vlevel = vlevel_split;
pipe_idx++;
}
context->bw_ctx.dml.vba.maxMpcComb = 0;
}
/* Split loop sets which pipe should be split based on dml outputs and dc flags */
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
if (!context->res_ctx.pipe_ctx[i].stream)
continue;
for (; vlevel_unsplit <= context->bw_ctx.dml.soc.num_states; vlevel_unsplit++)
if (context->bw_ctx.dml.vba.NoOfDPP[vlevel_unsplit][0][pipe_idx] == 1)
break;
if (force_split || context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] > 1)
split[i] = true;
if ((pipe->stream->view_format ==
VIEW_3D_FORMAT_SIDE_BY_SIDE ||
pipe->stream->view_format ==
VIEW_3D_FORMAT_TOP_AND_BOTTOM) &&
(pipe->stream->timing.timing_3d_format ==
TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
pipe->stream->timing.timing_3d_format ==
TIMING_3D_FORMAT_SIDE_BY_SIDE))
split[i] = true;
if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) {
split[i] = true;
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx] = true;
}
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx] =
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
/* Adjust dppclk when split is forced, do not bother with dispclk */
if (split[i] && context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1)
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] /= 2;
pipe_idx++;
}
return vlevel;
}
bool dcn20_fast_validate_bw(
struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int *pipe_cnt_out,
int *pipe_split_from,
int *vlevel_out)
{
bool out = false;
bool split[MAX_PIPES] = { false };
int pipe_cnt, i, pipe_idx, vlevel;
ASSERT(pipes);
if (!pipes)
return false;
dcn20_merge_pipes_for_validate(dc, context);
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, &context->res_ctx, pipes);
*pipe_cnt_out = pipe_cnt;
if (!pipe_cnt) {
out = true;
goto validate_out;
}
vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
if (vlevel > context->bw_ctx.dml.soc.num_states)
goto validate_fail;
vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split);
/*initialize pipe_just_split_from to invalid idx*/
for (i = 0; i < MAX_PIPES; i++)
pipe_split_from[i] = -1;
for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe;
bool need_split = true;
bool need_split3d;
if (!pipe->stream || pipe_split_from[i] >= 0)
continue;
pipe_idx++;
if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) {
force_split = true;
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx] = true;
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx] = true;
}
if (force_split && context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1)
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] /= 2;
if (!pipe->top_pipe && !pipe->plane_state && context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
ASSERT(hsplit_pipe);
@@ -2437,35 +2506,20 @@ bool dcn20_fast_validate_bw(
if (pipe->top_pipe && pipe->plane_state == pipe->top_pipe->plane_state)
continue;
need_split3d = ((pipe->stream->view_format ==
VIEW_3D_FORMAT_SIDE_BY_SIDE ||
pipe->stream->view_format ==
VIEW_3D_FORMAT_TOP_AND_BOTTOM) &&
(pipe->stream->timing.timing_3d_format ==
TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
pipe->stream->timing.timing_3d_format ==
TIMING_3D_FORMAT_SIDE_BY_SIDE));
if (avoid_split && vlevel_unsplit <= context->bw_ctx.dml.soc.num_states && !force_split && !need_split3d) {
need_split = false;
vlevel = vlevel_unsplit;
context->bw_ctx.dml.vba.maxMpcComb = 0;
} else
need_split = context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 2;
/* We do not support mpo + odm at the moment */
if (hsplit_pipe && hsplit_pipe->plane_state != pipe->plane_state
&& context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx])
goto validate_fail;
if (need_split3d || need_split || force_split) {
if (split[i]) {
if (!hsplit_pipe || hsplit_pipe->plane_state != pipe->plane_state) {
/* pipe not split previously needs split */
hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
ASSERT(hsplit_pipe || force_split);
if (!hsplit_pipe)
ASSERT(hsplit_pipe);
if (!hsplit_pipe) {
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] *= 2;
continue;
}
if (context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
if (!dcn20_split_stream_for_odm(
&context->res_ctx, dc->res_pool,
@@ -2504,7 +2558,7 @@ validate_out:
return out;
}
void dcn20_calculate_wm(
static void dcn20_calculate_wm(
struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int *out_pipe_cnt,
@@ -2525,7 +2579,7 @@ void dcn20_calculate_wm(
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
pipes[pipe_cnt].pipe.dest.odm_combine =
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx];
else
pipes[pipe_cnt].pipe.dest.odm_combine = 0;
pipe_idx++;
@@ -2534,7 +2588,7 @@ void dcn20_calculate_wm(
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
pipes[pipe_cnt].pipe.dest.odm_combine =
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_split_from[i]];
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_split_from[i]];
else
pipes[pipe_cnt].pipe.dest.odm_combine = 0;
}
@@ -2580,6 +2634,7 @@ void dcn20_calculate_wm(
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
#endif
if (vlevel < 2) {
@@ -2905,6 +2960,7 @@ static struct resource_funcs dcn20_res_pool_funcs = {
.populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context,
.get_default_swizzle_mode = dcn20_get_default_swizzle_mode,
.set_mcif_arb_params = dcn20_set_mcif_arb_params,
.populate_dml_pipes = dcn20_populate_dml_pipes_from_context,
.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link
};
@@ -2913,8 +2969,6 @@ bool dcn20_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
int i;
uint32_t pipe_count = pool->res_cap->num_dwb;
ASSERT(pipe_count > 0);
for (i = 0; i < pipe_count; i++) {
struct dcn20_dwbc *dwbc20 = kzalloc(sizeof(struct dcn20_dwbc),
GFP_KERNEL);
@@ -2983,7 +3037,7 @@ static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
}
}
static void cap_soc_clocks(
void dcn20_cap_soc_clocks(
struct _vcs_dpi_soc_bounding_box_st *bb,
struct pp_smu_nv_clock_table max_clocks)
{
@@ -3050,7 +3104,7 @@ static void cap_soc_clocks(
}
}
static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states)
{
struct _vcs_dpi_voltage_scaling_st calculated_states[MAX_CLOCK_LIMIT_STATES];
@@ -3065,10 +3119,14 @@ static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_
if (dc->bb_overrides.min_dcfclk_mhz > 0)
min_dcfclk = dc->bb_overrides.min_dcfclk_mhz;
else
// Accounting for SOC/DCF relationship, we can go as high as
// 506Mhz in Vmin. We need to code 507 since SMU will round down to 506.
min_dcfclk = 507;
else {
if (ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev))
min_dcfclk = 310;
else
// Accounting for SOC/DCF relationship, we can go as high as
// 506Mhz in Vmin.
min_dcfclk = 506;
}
for (i = 0; i < num_states; i++) {
int min_fclk_required_by_uclk;
@@ -3108,7 +3166,7 @@ static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_
bb->clock_limits[num_calculated_states].state = bb->num_states;
}
static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
{
kernel_fpu_begin();
if ((int)(bb->sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns
@@ -3307,14 +3365,14 @@ static bool init_soc_bounding_box(struct dc *dc,
}
if (clock_limits_available && uclk_states_available && num_states)
update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states);
dcn20_update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states);
else if (clock_limits_available)
cap_soc_clocks(loaded_bb, max_clocks);
dcn20_cap_soc_clocks(loaded_bb, max_clocks);
}
loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
loaded_ip->max_num_dpp = pool->base.pipe_count;
patch_bounding_box(dc, loaded_bb);
dcn20_patch_bounding_box(dc, loaded_bb);
return true;
}

View File

@@ -95,6 +95,12 @@ struct display_stream_compressor *dcn20_dsc_create(
struct dc_context *ctx, uint32_t inst);
void dcn20_dsc_destroy(struct display_stream_compressor **dsc);
void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb);
void dcn20_cap_soc_clocks(
struct _vcs_dpi_soc_bounding_box_st *bb,
struct pp_smu_nv_clock_table max_clocks);
void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states);
struct hubp *dcn20_hubp_create(
struct dc_context *ctx,
uint32_t inst);
@@ -113,6 +119,31 @@ void dcn20_set_mcif_arb_params(
display_e2e_pipe_params_st *pipes,
int pipe_cnt);
bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate);
void dcn20_merge_pipes_for_validate(
struct dc *dc,
struct dc_state *context);
int dcn20_validate_apply_pipe_split_flags(
struct dc *dc,
struct dc_state *context,
int vlevel,
bool *split);
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx);
#endif
void dcn20_split_stream_for_mpc(
struct resource_context *res_ctx,
const struct resource_pool *pool,
struct pipe_ctx *primary_pipe,
struct pipe_ctx *secondary_pipe);
bool dcn20_split_stream_for_odm(
struct resource_context *res_ctx,
const struct resource_pool *pool,
struct pipe_ctx *prev_odm_pipe,
struct pipe_ctx *next_odm_pipe);
struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
struct resource_context *res_ctx,
const struct resource_pool *pool,
const struct pipe_ctx *primary_pipe);
bool dcn20_fast_validate_bw(
struct dc *dc,
struct dc_state *context,

View File

@@ -83,8 +83,8 @@
struct _vcs_dpi_ip_params_st dcn2_1_ip = {
.odm_capable = 1,
.gpuvm_enable = 0,
.hostvm_enable = 0,
.gpuvm_enable = 1,
.hostvm_enable = 1,
.gpuvm_max_page_table_levels = 1,
.hostvm_max_page_table_levels = 4,
.hostvm_cached_page_table_levels = 2,
@@ -669,6 +669,9 @@ static const struct dcn10_stream_encoder_mask se_mask = {
static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
static int dcn21_populate_dml_pipes_from_context(
struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes);
static struct input_pixel_processor *dcn21_ipp_create(
struct dc_context *ctx, uint32_t inst)
{
@@ -833,7 +836,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.clock_trace = true,
.disable_pplib_clock_request = true,
.pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
.force_single_disp_pipe_split = true,
.force_single_disp_pipe_split = false,
.disable_dcc = DCC_ENABLE,
.vsr_support = true,
.performance_trace = false,
@@ -1006,6 +1009,7 @@ static void calculate_wm_set_for_vlevel(
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
#endif
dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
@@ -1083,7 +1087,7 @@ void dcn21_calculate_wm(
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
&context->res_ctx, pipes);
else
pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
pipe_cnt = dcn21_populate_dml_pipes_from_context(dc,
&context->res_ctx, pipes);
}
@@ -1333,6 +1337,12 @@ struct display_stream_compressor *dcn21_dsc_create(
static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
{
/*
TODO: Fix this function to calcualte correct values.
There are known issues with this function currently
that will need to be investigated. Use hardcoded known good values for now.
struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
struct clk_limit_table *clk_table = &bw_params->clk_table;
int i;
@@ -1347,11 +1357,11 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
dcn2_1_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
dcn2_1_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
/* This is probably wrong, TODO: find correct calculation */
dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000;
}
dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - i];
dcn2_1_soc.num_states = i;
*/
}
/* Temporary Place holder until we can get them from fuse */
@@ -1552,19 +1562,48 @@ static const struct dcn10_link_enc_mask le_mask = {
LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK)
};
static int map_transmitter_id_to_phy_instance(
enum transmitter transmitter)
{
switch (transmitter) {
case TRANSMITTER_UNIPHY_A:
return 0;
break;
case TRANSMITTER_UNIPHY_B:
return 1;
break;
case TRANSMITTER_UNIPHY_C:
return 2;
break;
case TRANSMITTER_UNIPHY_D:
return 3;
break;
case TRANSMITTER_UNIPHY_E:
return 4;
break;
default:
ASSERT(0);
return 0;
}
}
static struct link_encoder *dcn21_link_encoder_create(
const struct encoder_init_data *enc_init_data)
{
struct dcn21_link_encoder *enc21 =
kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL);
int link_regs_id;
if (!enc21)
return NULL;
link_regs_id =
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
dcn21_link_encoder_construct(enc21,
enc_init_data,
&link_enc_feature,
&link_enc_regs[enc_init_data->transmitter],
&link_enc_regs[link_regs_id],
&link_enc_aux_regs[enc_init_data->channel - 1],
&link_enc_hpd_regs[enc_init_data->hpd_source],
&le_shift,
@@ -1585,10 +1624,29 @@ static uint32_t read_pipe_fuses(struct dc_context *ctx)
return value;
}
static int dcn21_populate_dml_pipes_from_context(
struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
{
uint32_t pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, res_ctx, pipes);
int i;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
if (!res_ctx->pipe_ctx[i].stream)
continue;
pipes[i].pipe.src.hostvm = 1;
pipes[i].pipe.src.gpuvm = 1;
}
return pipe_cnt;
}
static struct resource_funcs dcn21_res_pool_funcs = {
.destroy = dcn21_destroy_resource_pool,
.link_enc_create = dcn21_link_encoder_create,
.validate_bandwidth = dcn21_validate_bandwidth,
.populate_dml_pipes = dcn21_populate_dml_pipes_from_context,
.add_stream_to_ctx = dcn20_add_stream_to_ctx,
.remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
@@ -1608,6 +1666,7 @@ static bool construct(
struct dc_context *ctx = dc->ctx;
struct irq_service_init_data init_data;
uint32_t pipe_fuses = read_pipe_fuses(ctx);
uint32_t num_pipes;
ctx->dc_bios->regs = &bios_regs;
@@ -1721,6 +1780,14 @@ static bool construct(
pool->base.pp_smu = dcn21_pp_smu_create(ctx);
num_pipes = dcn2_1_ip.max_num_dpp;
for (i = 0; i < dcn2_1_ip.max_num_dpp; i++)
if (pipe_fuses & 1 << i)
num_pipes--;
dcn2_1_ip.max_num_dpp = num_pipes;
dcn2_1_ip.max_num_otg = num_pipes;
dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
init_data.ctx = dc->ctx;

View File

@@ -251,8 +251,8 @@ struct pp_smu_funcs_nv {
#define PP_SMU_NUM_SOCCLK_DPM_LEVELS 8
#define PP_SMU_NUM_DCFCLK_DPM_LEVELS 8
#define PP_SMU_NUM_FCLK_DPM_LEVELS 8
#define PP_SMU_NUM_MEMCLK_DPM_LEVELS 8
#define PP_SMU_NUM_FCLK_DPM_LEVELS 4
#define PP_SMU_NUM_MEMCLK_DPM_LEVELS 4
struct dpm_clock {
uint32_t Freq; // In MHz

View File

@@ -2577,7 +2577,8 @@ static void dml20_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPer
mode_lib->vba.MinActiveDRAMClockChangeMargin
+ mode_lib->vba.DRAMClockChangeLatency;
if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 50) {
mode_lib->vba.DRAMClockChangeWatermark += 25;
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
} else {
if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {

View File

@@ -2611,7 +2611,8 @@ static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndP
mode_lib->vba.MinActiveDRAMClockChangeMargin
+ mode_lib->vba.DRAMClockChangeLatency;
if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 50) {
mode_lib->vba.DRAMClockChangeWatermark += 25;
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
} else {
if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {

View File

@@ -318,6 +318,7 @@ struct _vcs_dpi_display_pipe_dest_params_st {
unsigned int vupdate_width;
unsigned int vready_offset;
unsigned char interlaced;
unsigned char embedded;
double pixel_rate_mhz;
unsigned char synchronized_vblank_all_planes;
unsigned char otg_inst;

View File

@@ -375,6 +375,7 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
mode_lib->vba.EmbeddedPanel[mode_lib->vba.NumberOfActivePlanes] = dst->embedded;
mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
(enum scan_direction_class) (src->source_scan);
@@ -432,6 +433,8 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
dst->odm_combine;
mode_lib->vba.ODMCombineTypeEnabled[mode_lib->vba.NumberOfActivePlanes] =
dst->odm_combine;
mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
(enum output_format_class) (dout->output_format);
mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] =

View File

@@ -387,6 +387,7 @@ struct vba_vars_st {
/* vba mode support */
/*inputs*/
bool EmbeddedPanel[DC__NUM_DPP__MAX];
bool SupportGFX7CompatibleTilingIn32bppAnd64bpp;
double MaxHSCLRatio;
double MaxVSCLRatio;

View File

@@ -174,9 +174,7 @@ static bool hdmi_14_process_transaction(
link->ctx,
link,
&i2c_command);
if (buff)
kfree(buff);
kfree(buff);
return result;
}

View File

@@ -398,10 +398,6 @@ struct dc_state {
struct clk_mgr *clk_mgr;
struct {
bool full_update_needed : 1;
} commit_hints;
struct kref refcount;
};

View File

@@ -149,7 +149,6 @@ struct wm_table {
struct clk_bw_params {
unsigned int vram_type;
unsigned int num_channels;
unsigned int dispclk_vco_khz;
struct clk_limit_table clk_table;
struct wm_table wm_table;
};
@@ -184,6 +183,7 @@ struct clk_mgr_funcs {
bool (*are_clock_states_equal) (struct dc_clocks *a,
struct dc_clocks *b);
void (*notify_wm_ranges)(struct clk_mgr *clk_mgr);
};
struct clk_mgr {
@@ -192,6 +192,7 @@ struct clk_mgr {
struct dc_clocks clks;
bool psr_allow_active_cache;
int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes
int dentist_vco_freq_khz;
#ifdef CONFIG_DRM_AMD_DC_DCN2_1
struct clk_bw_params *bw_params;
#endif

View File

@@ -225,8 +225,6 @@ struct clk_mgr_internal {
struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES];
/*TODO: figure out which of the below fields should be here vs in asic specific portion */
int dentist_vco_freq_khz;
/* Cache the status of DFS-bypass feature*/
bool dfs_bypass_enabled;
/* True if the DFS-bypass feature is enabled and active. */