mirror of
https://github.com/torvalds/linux.git
synced 2026-04-26 02:22:28 -04:00
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:
@@ -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*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) ||
|
||||
|
||||
@@ -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.*/
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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] =
|
||||
|
||||
@@ -387,6 +387,7 @@ struct vba_vars_st {
|
||||
|
||||
/* vba mode support */
|
||||
/*inputs*/
|
||||
bool EmbeddedPanel[DC__NUM_DPP__MAX];
|
||||
bool SupportGFX7CompatibleTilingIn32bppAnd64bpp;
|
||||
double MaxHSCLRatio;
|
||||
double MaxVSCLRatio;
|
||||
|
||||
@@ -174,9 +174,7 @@ static bool hdmi_14_process_transaction(
|
||||
link->ctx,
|
||||
link,
|
||||
&i2c_command);
|
||||
|
||||
if (buff)
|
||||
kfree(buff);
|
||||
kfree(buff);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -398,10 +398,6 @@ struct dc_state {
|
||||
|
||||
struct clk_mgr *clk_mgr;
|
||||
|
||||
struct {
|
||||
bool full_update_needed : 1;
|
||||
} commit_hints;
|
||||
|
||||
struct kref refcount;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user