Skip to content

Commit a9b1a4f

Browse files
Nicholas Kazlauskasalexdeucher
authored andcommitted
drm/amd/display: Add more checks for exiting idle in DC
[Why] Any interface that touches registers needs to wake up the system. [How] Add a new interface dc_exit_ips_for_hw_access that wraps the check for IPS support and insert it into the public DC interfaces that touch registers. We don't re-enter, since we expect that the enter/exit to have been done on the DM side. Cc: [email protected] # 6.1+ Reviewed-by: Ovidiu Bunea <[email protected]> Acked-by: Hamza Mahfooz <[email protected]> Signed-off-by: Nicholas Kazlauskas <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent db83914 commit a9b1a4f

File tree

4 files changed

+63
-0
lines changed

4 files changed

+63
-0
lines changed

drivers/gpu/drm/amd/display/dc/core/dc.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,8 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
417417
if (!memcmp(&stream->adjust, adjust, sizeof(*adjust)))
418418
return true;
419419

420+
dc_exit_ips_for_hw_access(dc);
421+
420422
stream->adjust.v_total_max = adjust->v_total_max;
421423
stream->adjust.v_total_mid = adjust->v_total_mid;
422424
stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
@@ -457,6 +459,8 @@ bool dc_stream_get_last_used_drr_vtotal(struct dc *dc,
457459

458460
int i = 0;
459461

462+
dc_exit_ips_for_hw_access(dc);
463+
460464
for (i = 0; i < MAX_PIPES; i++) {
461465
struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
462466

@@ -487,6 +491,8 @@ bool dc_stream_get_crtc_position(struct dc *dc,
487491
bool ret = false;
488492
struct crtc_position position;
489493

494+
dc_exit_ips_for_hw_access(dc);
495+
490496
for (i = 0; i < MAX_PIPES; i++) {
491497
struct pipe_ctx *pipe =
492498
&dc->current_state->res_ctx.pipe_ctx[i];
@@ -606,6 +612,8 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
606612
if (pipe == NULL)
607613
return false;
608614

615+
dc_exit_ips_for_hw_access(dc);
616+
609617
/* By default, capture the full frame */
610618
param.windowa_x_start = 0;
611619
param.windowa_y_start = 0;
@@ -665,6 +673,8 @@ bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
665673
struct pipe_ctx *pipe;
666674
struct timing_generator *tg;
667675

676+
dc_exit_ips_for_hw_access(dc);
677+
668678
for (i = 0; i < MAX_PIPES; i++) {
669679
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
670680
if (pipe->stream == stream)
@@ -689,6 +699,8 @@ void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream,
689699
int i;
690700
struct pipe_ctx *pipe_ctx;
691701

702+
dc_exit_ips_for_hw_access(dc);
703+
692704
for (i = 0; i < MAX_PIPES; i++) {
693705
if (dc->current_state->res_ctx.pipe_ctx[i].stream
694706
== stream) {
@@ -724,6 +736,8 @@ void dc_stream_set_dither_option(struct dc_stream_state *stream,
724736
if (option > DITHER_OPTION_MAX)
725737
return;
726738

739+
dc_exit_ips_for_hw_access(stream->ctx->dc);
740+
727741
stream->dither_option = option;
728742

729743
memset(&params, 0, sizeof(params));
@@ -748,6 +762,8 @@ bool dc_stream_set_gamut_remap(struct dc *dc, const struct dc_stream_state *stre
748762
bool ret = false;
749763
struct pipe_ctx *pipes;
750764

765+
dc_exit_ips_for_hw_access(dc);
766+
751767
for (i = 0; i < MAX_PIPES; i++) {
752768
if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
753769
pipes = &dc->current_state->res_ctx.pipe_ctx[i];
@@ -765,6 +781,8 @@ bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream)
765781
bool ret = false;
766782
struct pipe_ctx *pipes;
767783

784+
dc_exit_ips_for_hw_access(dc);
785+
768786
for (i = 0; i < MAX_PIPES; i++) {
769787
if (dc->current_state->res_ctx.pipe_ctx[i].stream
770788
== stream) {
@@ -791,6 +809,8 @@ void dc_stream_set_static_screen_params(struct dc *dc,
791809
struct pipe_ctx *pipes_affected[MAX_PIPES];
792810
int num_pipes_affected = 0;
793811

812+
dc_exit_ips_for_hw_access(dc);
813+
794814
for (i = 0; i < num_streams; i++) {
795815
struct dc_stream_state *stream = streams[i];
796816

@@ -1769,6 +1789,8 @@ void dc_enable_stereo(
17691789
int i, j;
17701790
struct pipe_ctx *pipe;
17711791

1792+
dc_exit_ips_for_hw_access(dc);
1793+
17721794
for (i = 0; i < MAX_PIPES; i++) {
17731795
if (context != NULL) {
17741796
pipe = &context->res_ctx.pipe_ctx[i];
@@ -1788,6 +1810,8 @@ void dc_enable_stereo(
17881810
void dc_trigger_sync(struct dc *dc, struct dc_state *context)
17891811
{
17901812
if (context->stream_count > 1 && !dc->debug.disable_timing_sync) {
1813+
dc_exit_ips_for_hw_access(dc);
1814+
17911815
enable_timing_multisync(dc, context);
17921816
program_timing_sync(dc, context);
17931817
}
@@ -2044,6 +2068,8 @@ enum dc_status dc_commit_streams(struct dc *dc,
20442068
if (!streams_changed(dc, streams, stream_count))
20452069
return res;
20462070

2071+
dc_exit_ips_for_hw_access(dc);
2072+
20472073
DC_LOG_DC("%s: %d streams\n", __func__, stream_count);
20482074

20492075
for (i = 0; i < stream_count; i++) {
@@ -3373,6 +3399,8 @@ static void commit_planes_for_stream_fast(struct dc *dc,
33733399
int i, j;
33743400
struct pipe_ctx *top_pipe_to_program = NULL;
33753401
struct dc_stream_status *stream_status = NULL;
3402+
dc_exit_ips_for_hw_access(dc);
3403+
33763404
dc_z10_restore(dc);
33773405

33783406
top_pipe_to_program = resource_get_otg_master_for_stream(
@@ -3527,6 +3555,8 @@ static void commit_planes_for_stream(struct dc *dc,
35273555
// dc->current_state anymore, so we have to cache it before we apply
35283556
// the new SubVP context
35293557
subvp_prev_use = false;
3558+
dc_exit_ips_for_hw_access(dc);
3559+
35303560
dc_z10_restore(dc);
35313561
if (update_type == UPDATE_TYPE_FULL)
35323562
wait_for_outstanding_hw_updates(dc, context);
@@ -4409,6 +4439,8 @@ bool dc_update_planes_and_stream(struct dc *dc,
44094439
bool is_plane_addition = 0;
44104440
bool is_fast_update_only;
44114441

4442+
dc_exit_ips_for_hw_access(dc);
4443+
44124444
populate_fast_updates(fast_update, srf_updates, surface_count, stream_update);
44134445
is_fast_update_only = fast_update_only(dc, fast_update, srf_updates,
44144446
surface_count, stream_update, stream);
@@ -4529,6 +4561,8 @@ void dc_commit_updates_for_stream(struct dc *dc,
45294561
int i, j;
45304562
struct dc_fast_update fast_update[MAX_SURFACES] = {0};
45314563

4564+
dc_exit_ips_for_hw_access(dc);
4565+
45324566
populate_fast_updates(fast_update, srf_updates, surface_count, stream_update);
45334567
stream_status = dc_stream_get_status(stream);
45344568
context = dc->current_state;
@@ -4713,6 +4747,8 @@ void dc_set_power_state(
47134747
case DC_ACPI_CM_POWER_STATE_D0:
47144748
dc_state_construct(dc, dc->current_state);
47154749

4750+
dc_exit_ips_for_hw_access(dc);
4751+
47164752
dc_z10_restore(dc);
47174753

47184754
dc->hwss.init_hw(dc);
@@ -4854,6 +4890,12 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow)
48544890
dc->idle_optimizations_allowed = allow;
48554891
}
48564892

4893+
void dc_exit_ips_for_hw_access(struct dc *dc)
4894+
{
4895+
if (dc->caps.ips_support)
4896+
dc_allow_idle_optimizations(dc, false);
4897+
}
4898+
48574899
bool dc_dmub_is_ips_idle_state(struct dc *dc)
48584900
{
48594901
uint32_t idle_state = 0;

drivers/gpu/drm/amd/display/dc/core/dc_stream.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,8 @@ bool dc_stream_add_writeback(struct dc *dc,
423423
return false;
424424
}
425425

426+
dc_exit_ips_for_hw_access(dc);
427+
426428
wb_info->dwb_params.out_transfer_func = stream->out_transfer_func;
427429

428430
dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst];
@@ -493,6 +495,8 @@ bool dc_stream_fc_disable_writeback(struct dc *dc,
493495
return false;
494496
}
495497

498+
dc_exit_ips_for_hw_access(dc);
499+
496500
if (dwb->funcs->set_fc_enable)
497501
dwb->funcs->set_fc_enable(dwb, DWB_FRAME_CAPTURE_DISABLE);
498502

@@ -542,6 +546,8 @@ bool dc_stream_remove_writeback(struct dc *dc,
542546
return false;
543547
}
544548

549+
dc_exit_ips_for_hw_access(dc);
550+
545551
/* disable writeback */
546552
if (dc->hwss.disable_writeback) {
547553
struct dwbc *dwb = dc->res_pool->dwbc[dwb_pipe_inst];
@@ -557,6 +563,8 @@ bool dc_stream_warmup_writeback(struct dc *dc,
557563
int num_dwb,
558564
struct dc_writeback_info *wb_info)
559565
{
566+
dc_exit_ips_for_hw_access(dc);
567+
560568
if (dc->hwss.mmhubbub_warmup)
561569
return dc->hwss.mmhubbub_warmup(dc, num_dwb, wb_info);
562570
else
@@ -569,6 +577,8 @@ uint32_t dc_stream_get_vblank_counter(const struct dc_stream_state *stream)
569577
struct resource_context *res_ctx =
570578
&dc->current_state->res_ctx;
571579

580+
dc_exit_ips_for_hw_access(dc);
581+
572582
for (i = 0; i < MAX_PIPES; i++) {
573583
struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg;
574584

@@ -597,6 +607,8 @@ bool dc_stream_send_dp_sdp(const struct dc_stream_state *stream,
597607
dc = stream->ctx->dc;
598608
res_ctx = &dc->current_state->res_ctx;
599609

610+
dc_exit_ips_for_hw_access(dc);
611+
600612
for (i = 0; i < MAX_PIPES; i++) {
601613
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
602614

@@ -628,6 +640,8 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
628640
struct resource_context *res_ctx =
629641
&dc->current_state->res_ctx;
630642

643+
dc_exit_ips_for_hw_access(dc);
644+
631645
for (i = 0; i < MAX_PIPES; i++) {
632646
struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg;
633647

@@ -664,6 +678,8 @@ bool dc_stream_dmdata_status_done(struct dc *dc, struct dc_stream_state *stream)
664678
if (i == MAX_PIPES)
665679
return true;
666680

681+
dc_exit_ips_for_hw_access(dc);
682+
667683
return dc->hwss.dmdata_status_done(pipe);
668684
}
669685

@@ -698,6 +714,8 @@ bool dc_stream_set_dynamic_metadata(struct dc *dc,
698714

699715
pipe_ctx->stream->dmdata_address = attr->address;
700716

717+
dc_exit_ips_for_hw_access(dc);
718+
701719
dc->hwss.program_dmdata_engine(pipe_ctx);
702720

703721
if (hubp->funcs->dmdata_set_attributes != NULL &&

drivers/gpu/drm/amd/display/dc/core/dc_surface.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ const struct dc_plane_status *dc_plane_get_status(
161161
break;
162162
}
163163

164+
dc_exit_ips_for_hw_access(dc);
165+
164166
for (i = 0; i < dc->res_pool->pipe_count; i++) {
165167
struct pipe_ctx *pipe_ctx =
166168
&dc->current_state->res_ctx.pipe_ctx[i];

drivers/gpu/drm/amd/display/dc/dc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2325,6 +2325,7 @@ bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct dc_plane_
23252325
struct dc_cursor_attributes *cursor_attr);
23262326

23272327
void dc_allow_idle_optimizations(struct dc *dc, bool allow);
2328+
void dc_exit_ips_for_hw_access(struct dc *dc);
23282329
bool dc_dmub_is_ips_idle_state(struct dc *dc);
23292330

23302331
/* set min and max memory clock to lowest and highest DPM level, respectively */

0 commit comments

Comments
 (0)