mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 06:34:12 +08:00
amd-drm-fixes-6.8-2024-02-08:
amdgpu: - Misc NULL/bounds check fixes - ODM pipe policy fix - Aborted suspend fixes - JPEG 4.0.5 fix - DCN 3.5 fixes - PSP fix - DP MST fix - Phantom pipe fix - VRAM vendor fix - Clang fix - SR-IOV fix -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCZcUGhAAKCRC93/aFa7yZ 2Pp8AP4shwYR9OwKXx13nspSD/le4qvxHRrodeaBtSARWYXDywEA9wt+NZ3r/izk 80R970NODmOawhixNRex08ggd2TTZwg= =25qe -----END PGP SIGNATURE----- Merge tag 'amd-drm-fixes-6.8-2024-02-08' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes amd-drm-fixes-6.8-2024-02-08: amdgpu: - Misc NULL/bounds check fixes - ODM pipe policy fix - Aborted suspend fixes - JPEG 4.0.5 fix - DCN 3.5 fixes - PSP fix - DP MST fix - Phantom pipe fix - VRAM vendor fix - Clang fix - SR-IOV fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240208165500.4887-1-alexander.deucher@amd.com
This commit is contained in:
commit
b30bed9d00
@ -1078,6 +1078,8 @@ struct amdgpu_device {
|
||||
bool in_s3;
|
||||
bool in_s4;
|
||||
bool in_s0ix;
|
||||
/* indicate amdgpu suspension status */
|
||||
bool suspend_complete;
|
||||
|
||||
enum pp_mp1_state mp1_state;
|
||||
struct amdgpu_doorbell_index doorbell_index;
|
||||
|
@ -2476,6 +2476,7 @@ static int amdgpu_pmops_suspend(struct device *dev)
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
|
||||
adev->suspend_complete = false;
|
||||
if (amdgpu_acpi_is_s0ix_active(adev))
|
||||
adev->in_s0ix = true;
|
||||
else if (amdgpu_acpi_is_s3_active(adev))
|
||||
@ -2490,6 +2491,7 @@ static int amdgpu_pmops_suspend_noirq(struct device *dev)
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
|
||||
adev->suspend_complete = true;
|
||||
if (amdgpu_acpi_should_gpu_reset(adev))
|
||||
return amdgpu_asic_reset(adev);
|
||||
|
||||
|
@ -362,7 +362,7 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_to_user((char *)buf, context->mem_context.shared_buf, shared_buf_len))
|
||||
if (copy_to_user((char *)&buf[copy_pos], context->mem_context.shared_buf, shared_buf_len))
|
||||
ret = -EFAULT;
|
||||
|
||||
err_free_shared_buf:
|
||||
|
@ -3034,6 +3034,14 @@ static int gfx_v9_0_cp_gfx_start(struct amdgpu_device *adev)
|
||||
|
||||
gfx_v9_0_cp_gfx_enable(adev, true);
|
||||
|
||||
/* Now only limit the quirk on the APU gfx9 series and already
|
||||
* confirmed that the APU gfx10/gfx11 needn't such update.
|
||||
*/
|
||||
if (adev->flags & AMD_IS_APU &&
|
||||
adev->in_s3 && !adev->suspend_complete) {
|
||||
DRM_INFO(" Will skip the CSB packet resubmit\n");
|
||||
return 0;
|
||||
}
|
||||
r = amdgpu_ring_alloc(ring, gfx_v9_0_get_csb_size(adev) + 4 + 3);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r);
|
||||
|
@ -1947,14 +1947,6 @@ static int gmc_v9_0_init_mem_ranges(struct amdgpu_device *adev)
|
||||
|
||||
static void gmc_v9_4_3_init_vram_info(struct amdgpu_device *adev)
|
||||
{
|
||||
static const u32 regBIF_BIOS_SCRATCH_4 = 0x50;
|
||||
u32 vram_info;
|
||||
|
||||
/* Only for dGPU, vendor informaton is reliable */
|
||||
if (!amdgpu_sriov_vf(adev) && !(adev->flags & AMD_IS_APU)) {
|
||||
vram_info = RREG32(regBIF_BIOS_SCRATCH_4);
|
||||
adev->gmc.vram_vendor = vram_info & 0xF;
|
||||
}
|
||||
adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM;
|
||||
adev->gmc.vram_width = 128 * 64;
|
||||
}
|
||||
|
@ -674,14 +674,6 @@ static int jpeg_v4_0_set_powergating_state(void *handle,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int jpeg_v4_0_set_interrupt_state(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
unsigned type,
|
||||
enum amdgpu_interrupt_state state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jpeg_v4_0_set_ras_interrupt_state(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
unsigned int type,
|
||||
@ -765,7 +757,6 @@ static void jpeg_v4_0_set_dec_ring_funcs(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
static const struct amdgpu_irq_src_funcs jpeg_v4_0_irq_funcs = {
|
||||
.set = jpeg_v4_0_set_interrupt_state,
|
||||
.process = jpeg_v4_0_process_interrupt,
|
||||
};
|
||||
|
||||
|
@ -181,7 +181,6 @@ static int jpeg_v4_0_5_hw_fini(void *handle)
|
||||
RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS))
|
||||
jpeg_v4_0_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
|
||||
}
|
||||
amdgpu_irq_put(adev, &adev->jpeg.inst->irq, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -516,14 +515,6 @@ static int jpeg_v4_0_5_set_powergating_state(void *handle,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int jpeg_v4_0_5_set_interrupt_state(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
unsigned type,
|
||||
enum amdgpu_interrupt_state state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jpeg_v4_0_5_process_interrupt(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
@ -603,7 +594,6 @@ static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
static const struct amdgpu_irq_src_funcs jpeg_v4_0_5_irq_funcs = {
|
||||
.set = jpeg_v4_0_5_set_interrupt_state,
|
||||
.process = jpeg_v4_0_5_process_interrupt,
|
||||
};
|
||||
|
||||
|
@ -431,6 +431,12 @@ static void nbio_v7_9_init_registers(struct amdgpu_device *adev)
|
||||
u32 inst_mask;
|
||||
int i;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
adev->rmmio_remap.reg_offset =
|
||||
SOC15_REG_OFFSET(
|
||||
NBIO, 0,
|
||||
regBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL)
|
||||
<< 2;
|
||||
WREG32_SOC15(NBIO, 0, regXCC_DOORBELL_FENCE,
|
||||
0xff & ~(adev->gfx.xcc_mask));
|
||||
|
||||
|
@ -1298,10 +1298,32 @@ static int soc15_common_suspend(void *handle)
|
||||
return soc15_common_hw_fini(adev);
|
||||
}
|
||||
|
||||
static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 sol_reg;
|
||||
|
||||
sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
|
||||
|
||||
/* Will reset for the following suspend abort cases.
|
||||
* 1) Only reset limit on APU side, dGPU hasn't checked yet.
|
||||
* 2) S3 suspend abort and TOS already launched.
|
||||
*/
|
||||
if (adev->flags & AMD_IS_APU && adev->in_s3 &&
|
||||
!adev->suspend_complete &&
|
||||
sol_reg)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int soc15_common_resume(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (soc15_need_reset_on_resume(adev)) {
|
||||
dev_info(adev->dev, "S3 suspend abort case, let's reset ASIC.\n");
|
||||
soc15_asic_reset(adev);
|
||||
}
|
||||
return soc15_common_hw_init(adev);
|
||||
}
|
||||
|
||||
|
@ -10731,12 +10731,14 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (dc_resource_is_dsc_encoding_supported(dc)) {
|
||||
ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars);
|
||||
if (ret) {
|
||||
DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context, vars);
|
||||
if (ret) {
|
||||
|
@ -3817,7 +3817,9 @@ static void commit_planes_for_stream(struct dc *dc,
|
||||
* programming has completed (we turn on phantom OTG in order
|
||||
* to complete the plane disable for phantom pipes).
|
||||
*/
|
||||
dc->hwss.apply_ctx_to_hw(dc, context);
|
||||
|
||||
if (dc->hwss.disable_phantom_streams)
|
||||
dc->hwss.disable_phantom_streams(dc, context);
|
||||
}
|
||||
|
||||
if (update_type != UPDATE_TYPE_FAST)
|
||||
|
@ -291,11 +291,14 @@ void dc_state_destruct(struct dc_state *state)
|
||||
dc_stream_release(state->phantom_streams[i]);
|
||||
state->phantom_streams[i] = NULL;
|
||||
}
|
||||
state->phantom_stream_count = 0;
|
||||
|
||||
for (i = 0; i < state->phantom_plane_count; i++) {
|
||||
dc_plane_state_release(state->phantom_planes[i]);
|
||||
state->phantom_planes[i] = NULL;
|
||||
}
|
||||
state->phantom_plane_count = 0;
|
||||
|
||||
state->stream_mask = 0;
|
||||
memset(&state->res_ctx, 0, sizeof(state->res_ctx));
|
||||
memset(&state->pp_display_cfg, 0, sizeof(state->pp_display_cfg));
|
||||
|
@ -72,11 +72,11 @@ CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn10/dcn10_fpu.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/dcn20_fpu.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags) $(frame_warn_flag)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_ccflags) $(frame_warn_flag)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20v2.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_mode_vba_21.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_mode_vba_21.o := $(dml_ccflags) $(frame_warn_flag)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_rq_dlg_calc_21.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(frame_warn_flag)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags)
|
||||
|
@ -1288,7 +1288,7 @@ static bool update_pipes_with_split_flags(struct dc *dc, struct dc_state *contex
|
||||
return updated;
|
||||
}
|
||||
|
||||
static bool should_allow_odm_power_optimization(struct dc *dc,
|
||||
static bool should_apply_odm_power_optimization(struct dc *dc,
|
||||
struct dc_state *context, struct vba_vars_st *v, int *split,
|
||||
bool *merge)
|
||||
{
|
||||
@ -1392,9 +1392,12 @@ static void try_odm_power_optimization_and_revalidate(
|
||||
{
|
||||
int i;
|
||||
unsigned int new_vlevel;
|
||||
unsigned int cur_policy[MAX_PIPES];
|
||||
|
||||
for (i = 0; i < pipe_cnt; i++)
|
||||
for (i = 0; i < pipe_cnt; i++) {
|
||||
cur_policy[i] = pipes[i].pipe.dest.odm_combine_policy;
|
||||
pipes[i].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1;
|
||||
}
|
||||
|
||||
new_vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
|
||||
|
||||
@ -1403,6 +1406,9 @@ static void try_odm_power_optimization_and_revalidate(
|
||||
memset(merge, 0, MAX_PIPES * sizeof(bool));
|
||||
*vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, new_vlevel, split, merge);
|
||||
context->bw_ctx.dml.vba.VoltageLevel = *vlevel;
|
||||
} else {
|
||||
for (i = 0; i < pipe_cnt; i++)
|
||||
pipes[i].pipe.dest.odm_combine_policy = cur_policy[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1580,7 +1586,7 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
|
||||
}
|
||||
}
|
||||
|
||||
if (should_allow_odm_power_optimization(dc, context, vba, split, merge))
|
||||
if (should_apply_odm_power_optimization(dc, context, vba, split, merge))
|
||||
try_odm_power_optimization_and_revalidate(
|
||||
dc, context, pipes, split, merge, vlevel, *pipe_cnt);
|
||||
|
||||
@ -2209,6 +2215,7 @@ bool dcn32_internal_validate_bw(struct dc *dc,
|
||||
int i;
|
||||
|
||||
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
|
||||
if (!dc->config.enable_windowed_mpo_odm)
|
||||
dcn32_update_dml_pipes_odm_policy_based_on_context(dc, context, pipes);
|
||||
|
||||
/* repopulate_pipes = 1 means the pipes were either split or merged. In this case
|
||||
|
@ -1476,7 +1476,7 @@ static enum dc_status dce110_enable_stream_timing(
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
static enum dc_status apply_single_controller_ctx_to_hw(
|
||||
enum dc_status dce110_apply_single_controller_ctx_to_hw(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct dc_state *context,
|
||||
struct dc *dc)
|
||||
@ -2302,7 +2302,7 @@ enum dc_status dce110_apply_ctx_to_hw(
|
||||
if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe)
|
||||
continue;
|
||||
|
||||
status = apply_single_controller_ctx_to_hw(
|
||||
status = dce110_apply_single_controller_ctx_to_hw(
|
||||
pipe_ctx,
|
||||
context,
|
||||
dc);
|
||||
|
@ -39,6 +39,10 @@ enum dc_status dce110_apply_ctx_to_hw(
|
||||
struct dc *dc,
|
||||
struct dc_state *context);
|
||||
|
||||
enum dc_status dce110_apply_single_controller_ctx_to_hw(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct dc_state *context,
|
||||
struct dc *dc);
|
||||
|
||||
void dce110_enable_stream(struct pipe_ctx *pipe_ctx);
|
||||
|
||||
|
@ -2561,7 +2561,7 @@ void dcn20_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
tg->funcs->setup_vertical_interrupt2(tg, start_line);
|
||||
}
|
||||
|
||||
static void dcn20_reset_back_end_for_pipe(
|
||||
void dcn20_reset_back_end_for_pipe(
|
||||
struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct dc_state *context)
|
||||
|
@ -84,6 +84,10 @@ enum dc_status dcn20_enable_stream_timing(
|
||||
void dcn20_disable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx);
|
||||
void dcn20_enable_stream_gating(struct dc *dc, struct pipe_ctx *pipe_ctx);
|
||||
void dcn20_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx);
|
||||
void dcn20_reset_back_end_for_pipe(
|
||||
struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct dc_state *context);
|
||||
void dcn20_init_blank(
|
||||
struct dc *dc,
|
||||
struct timing_generator *tg);
|
||||
|
@ -206,16 +206,21 @@ void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
|
||||
void dcn21_set_pipe(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct abm *abm = pipe_ctx->stream_res.abm;
|
||||
uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
|
||||
struct timing_generator *tg = pipe_ctx->stream_res.tg;
|
||||
struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
|
||||
struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu;
|
||||
uint32_t otg_inst;
|
||||
|
||||
if (!abm && !tg && !panel_cntl)
|
||||
return;
|
||||
|
||||
otg_inst = tg->inst;
|
||||
|
||||
if (dmcu) {
|
||||
dce110_set_pipe(pipe_ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (abm && panel_cntl) {
|
||||
if (abm->funcs && abm->funcs->set_pipe_ex) {
|
||||
abm->funcs->set_pipe_ex(abm,
|
||||
otg_inst,
|
||||
@ -229,7 +234,6 @@ void dcn21_set_pipe(struct pipe_ctx *pipe_ctx)
|
||||
panel_cntl->pwrseq_inst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
@ -237,17 +241,20 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
|
||||
{
|
||||
struct dc_context *dc = pipe_ctx->stream->ctx;
|
||||
struct abm *abm = pipe_ctx->stream_res.abm;
|
||||
struct timing_generator *tg = pipe_ctx->stream_res.tg;
|
||||
struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
|
||||
uint32_t otg_inst;
|
||||
|
||||
if (!abm && !tg && !panel_cntl)
|
||||
return false;
|
||||
|
||||
otg_inst = tg->inst;
|
||||
|
||||
if (dc->dc->res_pool->dmcu) {
|
||||
dce110_set_backlight_level(pipe_ctx, backlight_pwm_u16_16, frame_ramp);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (abm != NULL) {
|
||||
uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
|
||||
|
||||
if (abm && panel_cntl) {
|
||||
if (abm->funcs && abm->funcs->set_pipe_ex) {
|
||||
abm->funcs->set_pipe_ex(abm,
|
||||
otg_inst,
|
||||
@ -261,10 +268,8 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
|
||||
panel_cntl->inst,
|
||||
panel_cntl->pwrseq_inst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (abm && abm->funcs && abm->funcs->set_backlight_level_pwm)
|
||||
if (abm->funcs && abm->funcs->set_backlight_level_pwm)
|
||||
abm->funcs->set_backlight_level_pwm(abm, backlight_pwm_u16_16,
|
||||
frame_ramp, 0, panel_cntl->inst);
|
||||
else
|
||||
|
@ -1474,9 +1474,44 @@ void dcn32_update_dsc_pg(struct dc *dc,
|
||||
}
|
||||
}
|
||||
|
||||
void dcn32_disable_phantom_streams(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
int i;
|
||||
|
||||
for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {
|
||||
struct pipe_ctx *pipe_ctx_old =
|
||||
&dc->current_state->res_ctx.pipe_ctx[i];
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (!pipe_ctx_old->stream)
|
||||
continue;
|
||||
|
||||
if (dc_state_get_pipe_subvp_type(dc->current_state, pipe_ctx_old) != SUBVP_PHANTOM)
|
||||
continue;
|
||||
|
||||
if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe)
|
||||
continue;
|
||||
|
||||
if (!pipe_ctx->stream || pipe_need_reprogram(pipe_ctx_old, pipe_ctx) ||
|
||||
(pipe_ctx->stream && dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM)) {
|
||||
struct clock_source *old_clk = pipe_ctx_old->clock_source;
|
||||
|
||||
if (hws->funcs.reset_back_end_for_pipe)
|
||||
hws->funcs.reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
|
||||
if (hws->funcs.enable_stream_gating)
|
||||
hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
|
||||
if (old_clk)
|
||||
old_clk->funcs->cs_power_down(old_clk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
unsigned int i;
|
||||
enum dc_status status = DC_OK;
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
@ -1497,16 +1532,39 @@ void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context)
|
||||
}
|
||||
}
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
|
||||
struct pipe_ctx *pipe_ctx_old =
|
||||
&dc->current_state->res_ctx.pipe_ctx[i];
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (new_pipe->stream && dc_state_get_pipe_subvp_type(context, new_pipe) == SUBVP_PHANTOM) {
|
||||
// If old context or new context has phantom pipes, apply
|
||||
// the phantom timings now. We can't change the phantom
|
||||
// pipe configuration safely without driver acquiring
|
||||
// the DMCUB lock first.
|
||||
dc->hwss.apply_ctx_to_hw(dc, context);
|
||||
break;
|
||||
if (pipe_ctx->stream == NULL)
|
||||
continue;
|
||||
|
||||
if (dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM)
|
||||
continue;
|
||||
|
||||
if (pipe_ctx->stream == pipe_ctx_old->stream &&
|
||||
pipe_ctx->stream->link->link_state_valid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
|
||||
continue;
|
||||
|
||||
if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe)
|
||||
continue;
|
||||
|
||||
if (hws->funcs.apply_single_controller_ctx_to_hw)
|
||||
status = hws->funcs.apply_single_controller_ctx_to_hw(
|
||||
pipe_ctx,
|
||||
context,
|
||||
dc);
|
||||
|
||||
ASSERT(status == DC_OK);
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_FP
|
||||
if (hws->funcs.resync_fifo_dccg_dio)
|
||||
hws->funcs.resync_fifo_dccg_dio(hws, dc, context);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,6 +111,8 @@ void dcn32_update_dsc_pg(struct dc *dc,
|
||||
|
||||
void dcn32_enable_phantom_streams(struct dc *dc, struct dc_state *context);
|
||||
|
||||
void dcn32_disable_phantom_streams(struct dc *dc, struct dc_state *context);
|
||||
|
||||
void dcn32_init_blank(
|
||||
struct dc *dc,
|
||||
struct timing_generator *tg);
|
||||
|
@ -109,6 +109,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
|
||||
.get_dcc_en_bits = dcn10_get_dcc_en_bits,
|
||||
.commit_subvp_config = dcn32_commit_subvp_config,
|
||||
.enable_phantom_streams = dcn32_enable_phantom_streams,
|
||||
.disable_phantom_streams = dcn32_disable_phantom_streams,
|
||||
.subvp_pipe_control_lock = dcn32_subvp_pipe_control_lock,
|
||||
.update_visual_confirm_color = dcn10_update_visual_confirm_color,
|
||||
.subvp_pipe_control_lock_fast = dcn32_subvp_pipe_control_lock_fast,
|
||||
@ -159,6 +160,8 @@ static const struct hwseq_private_funcs dcn32_private_funcs = {
|
||||
.set_pixels_per_cycle = dcn32_set_pixels_per_cycle,
|
||||
.resync_fifo_dccg_dio = dcn32_resync_fifo_dccg_dio,
|
||||
.is_dp_dig_pixel_rate_div_policy = dcn32_is_dp_dig_pixel_rate_div_policy,
|
||||
.apply_single_controller_ctx_to_hw = dce110_apply_single_controller_ctx_to_hw,
|
||||
.reset_back_end_for_pipe = dcn20_reset_back_end_for_pipe,
|
||||
};
|
||||
|
||||
void dcn32_hw_sequencer_init_functions(struct dc *dc)
|
||||
|
@ -379,6 +379,7 @@ struct hw_sequencer_funcs {
|
||||
struct dc_cursor_attributes *cursor_attr);
|
||||
void (*commit_subvp_config)(struct dc *dc, struct dc_state *context);
|
||||
void (*enable_phantom_streams)(struct dc *dc, struct dc_state *context);
|
||||
void (*disable_phantom_streams)(struct dc *dc, struct dc_state *context);
|
||||
void (*subvp_pipe_control_lock)(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
bool lock,
|
||||
|
@ -165,8 +165,15 @@ struct hwseq_private_funcs {
|
||||
void (*set_pixels_per_cycle)(struct pipe_ctx *pipe_ctx);
|
||||
void (*resync_fifo_dccg_dio)(struct dce_hwseq *hws, struct dc *dc,
|
||||
struct dc_state *context);
|
||||
enum dc_status (*apply_single_controller_ctx_to_hw)(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct dc_state *context,
|
||||
struct dc *dc);
|
||||
bool (*is_dp_dig_pixel_rate_div_policy)(struct pipe_ctx *pipe_ctx);
|
||||
#endif
|
||||
void (*reset_back_end_for_pipe)(struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct dc_state *context);
|
||||
};
|
||||
|
||||
struct dce_hwseq {
|
||||
|
@ -427,22 +427,18 @@ struct pipe_ctx *resource_get_primary_dpp_pipe(const struct pipe_ctx *dpp_pipe);
|
||||
int resource_get_mpc_slice_index(const struct pipe_ctx *dpp_pipe);
|
||||
|
||||
/*
|
||||
* Get number of MPC "cuts" of the plane associated with the pipe. MPC slice
|
||||
* count is equal to MPC splits + 1. For example if a plane is cut 3 times, it
|
||||
* will have 4 pieces of slice.
|
||||
* return - 0 if pipe is not used for a plane with MPCC combine. otherwise
|
||||
* the number of MPC "cuts" for the plane.
|
||||
* Get the number of MPC slices associated with the pipe.
|
||||
* The function returns 0 if the pipe is not associated with an MPC combine
|
||||
* pipe topology.
|
||||
*/
|
||||
int resource_get_mpc_slice_count(const struct pipe_ctx *opp_head);
|
||||
int resource_get_mpc_slice_count(const struct pipe_ctx *pipe);
|
||||
|
||||
/*
|
||||
* Get number of ODM "cuts" of the timing associated with the pipe. ODM slice
|
||||
* count is equal to ODM splits + 1. For example if a timing is cut 3 times, it
|
||||
* will have 4 pieces of slice.
|
||||
* return - 0 if pipe is not used for ODM combine. otherwise
|
||||
* the number of ODM "cuts" for the timing.
|
||||
* Get the number of ODM slices associated with the pipe.
|
||||
* The function returns 0 if the pipe is not associated with an ODM combine
|
||||
* pipe topology.
|
||||
*/
|
||||
int resource_get_odm_slice_count(const struct pipe_ctx *otg_master);
|
||||
int resource_get_odm_slice_count(const struct pipe_ctx *pipe);
|
||||
|
||||
/* Get the ODM slice index counting from 0 from left most slice */
|
||||
int resource_get_odm_slice_index(const struct pipe_ctx *opp_head);
|
||||
|
@ -999,7 +999,7 @@ static struct stream_encoder *dcn301_stream_encoder_create(enum engine_id eng_id
|
||||
vpg = dcn301_vpg_create(ctx, vpg_inst);
|
||||
afmt = dcn301_afmt_create(ctx, afmt_inst);
|
||||
|
||||
if (!enc1 || !vpg || !afmt) {
|
||||
if (!enc1 || !vpg || !afmt || eng_id >= ARRAY_SIZE(stream_enc_regs)) {
|
||||
kfree(enc1);
|
||||
kfree(vpg);
|
||||
kfree(afmt);
|
||||
|
@ -1829,7 +1829,21 @@ int dcn32_populate_dml_pipes_from_context(
|
||||
dcn32_zero_pipe_dcc_fraction(pipes, pipe_cnt);
|
||||
DC_FP_END();
|
||||
pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
|
||||
if (dc->config.enable_windowed_mpo_odm &&
|
||||
dc->debug.enable_single_display_2to1_odm_policy) {
|
||||
switch (resource_get_odm_slice_count(pipe)) {
|
||||
case 2:
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_2to1;
|
||||
break;
|
||||
case 4:
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_4to1;
|
||||
break;
|
||||
default:
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal;
|
||||
}
|
||||
} else {
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal;
|
||||
}
|
||||
pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256; // according to spreadsheet
|
||||
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
|
||||
pipes[pipe_cnt].pipe.scale_ratio_depth.lb_depth = dm_lb_19;
|
||||
|
@ -780,8 +780,8 @@ static const struct dc_debug_options debug_defaults_drv = {
|
||||
.disable_z10 = false,
|
||||
.ignore_pg = true,
|
||||
.psp_disabled_wa = true,
|
||||
.ips2_eval_delay_us = 200,
|
||||
.ips2_entry_delay_us = 400,
|
||||
.ips2_eval_delay_us = 1650,
|
||||
.ips2_entry_delay_us = 800,
|
||||
.static_screen_wait_frames = 2,
|
||||
};
|
||||
|
||||
@ -2130,6 +2130,7 @@ static bool dcn35_resource_construct(
|
||||
dc->dml2_options.dcn_pipe_count = pool->base.pipe_count;
|
||||
dc->dml2_options.use_native_pstate_optimization = true;
|
||||
dc->dml2_options.use_native_soc_bb_construction = true;
|
||||
dc->dml2_options.minimize_dispclk_using_odm = false;
|
||||
if (dc->config.EnableMinDispClkODM)
|
||||
dc->dml2_options.minimize_dispclk_using_odm = true;
|
||||
dc->dml2_options.enable_windowed_mpo_odm = dc->config.enable_windowed_mpo_odm;
|
||||
|
Loading…
Reference in New Issue
Block a user