mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
drm/amd/display: Destroy DC context while keeping DML and DML2
If there is memory pressure at suspend time then dynamically allocating a large structure as part of DC suspend code will fail. Instead re-use the same structures and clear all members except those that should be maintained. Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2362 Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
f7fbf79fb5
commit
06ad7e1642
@ -4781,12 +4781,6 @@ bool dc_set_power_state(
|
|||||||
struct dc *dc,
|
struct dc *dc,
|
||||||
enum dc_acpi_cm_power_state power_state)
|
enum dc_acpi_cm_power_state power_state)
|
||||||
{
|
{
|
||||||
struct kref refcount;
|
|
||||||
struct display_mode_lib *dml;
|
|
||||||
#ifdef CONFIG_DRM_AMD_DC_FP
|
|
||||||
struct dml2_context *dml2 = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!dc->current_state)
|
if (!dc->current_state)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -4805,40 +4799,9 @@ bool dc_set_power_state(
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef CONFIG_DRM_AMD_DC_FP
|
|
||||||
if (dc->debug.using_dml2)
|
|
||||||
dml2 = dc->current_state->bw_ctx.dml2;
|
|
||||||
#endif
|
|
||||||
ASSERT(dc->current_state->stream_count == 0);
|
ASSERT(dc->current_state->stream_count == 0);
|
||||||
/* Zero out the current context so that on resume we start with
|
|
||||||
* clean state, and dc hw programming optimizations will not
|
|
||||||
* cause any trouble.
|
|
||||||
*/
|
|
||||||
dml = kzalloc(sizeof(struct display_mode_lib),
|
|
||||||
GFP_KERNEL);
|
|
||||||
|
|
||||||
ASSERT(dml);
|
|
||||||
if (!dml)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* Preserve refcount */
|
|
||||||
refcount = dc->current_state->refcount;
|
|
||||||
/* Preserve display mode lib */
|
|
||||||
memcpy(dml, &dc->current_state->bw_ctx.dml, sizeof(struct display_mode_lib));
|
|
||||||
|
|
||||||
dc_resource_state_destruct(dc->current_state);
|
dc_resource_state_destruct(dc->current_state);
|
||||||
memset(dc->current_state, 0,
|
|
||||||
sizeof(*dc->current_state));
|
|
||||||
|
|
||||||
dc->current_state->refcount = refcount;
|
|
||||||
dc->current_state->bw_ctx.dml = *dml;
|
|
||||||
|
|
||||||
kfree(dml);
|
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_AMD_DC_FP
|
|
||||||
if (dc->debug.using_dml2)
|
|
||||||
dc->current_state->bw_ctx.dml2 = dml2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4487,6 +4487,18 @@ void dc_resource_state_destruct(struct dc_state *context)
|
|||||||
context->streams[i] = NULL;
|
context->streams[i] = NULL;
|
||||||
}
|
}
|
||||||
context->stream_count = 0;
|
context->stream_count = 0;
|
||||||
|
context->stream_mask = 0;
|
||||||
|
memset(&context->res_ctx, 0, sizeof(context->res_ctx));
|
||||||
|
memset(&context->pp_display_cfg, 0, sizeof(context->pp_display_cfg));
|
||||||
|
memset(&context->dcn_bw_vars, 0, sizeof(context->dcn_bw_vars));
|
||||||
|
context->clk_mgr = NULL;
|
||||||
|
memset(&context->bw_ctx.bw, 0, sizeof(context->bw_ctx.bw));
|
||||||
|
memset(context->block_sequence, 0, sizeof(context->block_sequence));
|
||||||
|
context->block_sequence_steps = 0;
|
||||||
|
memset(context->dc_dmub_cmd, 0, sizeof(context->dc_dmub_cmd));
|
||||||
|
context->dmub_cmd_count = 0;
|
||||||
|
memset(&context->perf_params, 0, sizeof(context->perf_params));
|
||||||
|
memset(&context->scratch, 0, sizeof(context->scratch));
|
||||||
}
|
}
|
||||||
|
|
||||||
void dc_resource_state_copy_construct(
|
void dc_resource_state_copy_construct(
|
||||||
|
Loading…
Reference in New Issue
Block a user