Skip to content

Commit aaf00e6

Browse files
committed
Merge tag 'drm-intel-fixes-2024-04-10' of https://anongit.freedesktop.org/git/drm/drm-intel into drm-fixes
Display fixes: - Couple CDCLK programming fixes (Ville) - HDCP related fix (Suraj) - 4 Bigjoiner related fixes (Ville) Core fix: - Fix for a circular locking around GuC on reset+wedged case (John) Signed-off-by: Dave Airlie <[email protected]> From: Rodrigo Vivi <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 718c4fb + dcd8992 commit aaf00e6

File tree

9 files changed

+79
-27
lines changed

9 files changed

+79
-27
lines changed

drivers/gpu/drm/i915/display/intel_cdclk.c

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,7 +2534,8 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
25342534
intel_atomic_get_old_cdclk_state(state);
25352535
const struct intel_cdclk_state *new_cdclk_state =
25362536
intel_atomic_get_new_cdclk_state(state);
2537-
enum pipe pipe = new_cdclk_state->pipe;
2537+
struct intel_cdclk_config cdclk_config;
2538+
enum pipe pipe;
25382539

25392540
if (!intel_cdclk_changed(&old_cdclk_state->actual,
25402541
&new_cdclk_state->actual))
@@ -2543,12 +2544,25 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
25432544
if (IS_DG2(i915))
25442545
intel_cdclk_pcode_pre_notify(state);
25452546

2546-
if (pipe == INVALID_PIPE ||
2547-
old_cdclk_state->actual.cdclk <= new_cdclk_state->actual.cdclk) {
2548-
drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
2547+
if (new_cdclk_state->disable_pipes) {
2548+
cdclk_config = new_cdclk_state->actual;
2549+
pipe = INVALID_PIPE;
2550+
} else {
2551+
if (new_cdclk_state->actual.cdclk >= old_cdclk_state->actual.cdclk) {
2552+
cdclk_config = new_cdclk_state->actual;
2553+
pipe = new_cdclk_state->pipe;
2554+
} else {
2555+
cdclk_config = old_cdclk_state->actual;
2556+
pipe = INVALID_PIPE;
2557+
}
25492558

2550-
intel_set_cdclk(i915, &new_cdclk_state->actual, pipe);
2559+
cdclk_config.voltage_level = max(new_cdclk_state->actual.voltage_level,
2560+
old_cdclk_state->actual.voltage_level);
25512561
}
2562+
2563+
drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
2564+
2565+
intel_set_cdclk(i915, &cdclk_config, pipe);
25522566
}
25532567

25542568
/**
@@ -2566,7 +2580,7 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
25662580
intel_atomic_get_old_cdclk_state(state);
25672581
const struct intel_cdclk_state *new_cdclk_state =
25682582
intel_atomic_get_new_cdclk_state(state);
2569-
enum pipe pipe = new_cdclk_state->pipe;
2583+
enum pipe pipe;
25702584

25712585
if (!intel_cdclk_changed(&old_cdclk_state->actual,
25722586
&new_cdclk_state->actual))
@@ -2575,12 +2589,15 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
25752589
if (IS_DG2(i915))
25762590
intel_cdclk_pcode_post_notify(state);
25772591

2578-
if (pipe != INVALID_PIPE &&
2579-
old_cdclk_state->actual.cdclk > new_cdclk_state->actual.cdclk) {
2580-
drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
2592+
if (!new_cdclk_state->disable_pipes &&
2593+
new_cdclk_state->actual.cdclk < old_cdclk_state->actual.cdclk)
2594+
pipe = new_cdclk_state->pipe;
2595+
else
2596+
pipe = INVALID_PIPE;
2597+
2598+
drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
25812599

2582-
intel_set_cdclk(i915, &new_cdclk_state->actual, pipe);
2583-
}
2600+
intel_set_cdclk(i915, &new_cdclk_state->actual, pipe);
25842601
}
25852602

25862603
static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state)
@@ -3058,6 +3075,7 @@ static struct intel_global_state *intel_cdclk_duplicate_state(struct intel_globa
30583075
return NULL;
30593076

30603077
cdclk_state->pipe = INVALID_PIPE;
3078+
cdclk_state->disable_pipes = false;
30613079

30623080
return &cdclk_state->base;
30633081
}
@@ -3236,6 +3254,8 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
32363254
if (ret)
32373255
return ret;
32383256

3257+
new_cdclk_state->disable_pipes = true;
3258+
32393259
drm_dbg_kms(&dev_priv->drm,
32403260
"Modeset required for cdclk change\n");
32413261
}

drivers/gpu/drm/i915/display/intel_cdclk.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ struct intel_cdclk_state {
5151

5252
/* bitmask of active pipes */
5353
u8 active_pipes;
54+
55+
/* update cdclk with pipes disabled */
56+
bool disable_pipes;
5457
};
5558

5659
int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state);

drivers/gpu/drm/i915/display/intel_ddi.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4256,7 +4256,12 @@ static bool m_n_equal(const struct intel_link_m_n *m_n_1,
42564256
static bool crtcs_port_sync_compatible(const struct intel_crtc_state *crtc_state1,
42574257
const struct intel_crtc_state *crtc_state2)
42584258
{
4259+
/*
4260+
* FIXME the modeset sequence is currently wrong and
4261+
* can't deal with bigjoiner + port sync at the same time.
4262+
*/
42594263
return crtc_state1->hw.active && crtc_state2->hw.active &&
4264+
!crtc_state1->bigjoiner_pipes && !crtc_state2->bigjoiner_pipes &&
42604265
crtc_state1->output_types == crtc_state2->output_types &&
42614266
crtc_state1->output_format == crtc_state2->output_format &&
42624267
crtc_state1->lane_count == crtc_state2->lane_count &&

drivers/gpu/drm/i915/display/intel_dp.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2725,7 +2725,11 @@ intel_dp_drrs_compute_config(struct intel_connector *connector,
27252725
intel_panel_downclock_mode(connector, &pipe_config->hw.adjusted_mode);
27262726
int pixel_clock;
27272727

2728-
if (has_seamless_m_n(connector))
2728+
/*
2729+
* FIXME all joined pipes share the same transcoder.
2730+
* Need to account for that when updating M/N live.
2731+
*/
2732+
if (has_seamless_m_n(connector) && !pipe_config->bigjoiner_pipes)
27292733
pipe_config->update_m_n = true;
27302734

27312735
if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {

drivers/gpu/drm/i915/display/intel_dp_hdcp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,12 +691,15 @@ int intel_dp_hdcp_get_remote_capability(struct intel_connector *connector,
691691
u8 bcaps;
692692
int ret;
693693

694+
*hdcp_capable = false;
695+
*hdcp2_capable = false;
694696
if (!intel_encoder_is_mst(connector->encoder))
695697
return -EINVAL;
696698

697699
ret = _intel_dp_hdcp2_get_capability(aux, hdcp2_capable);
698700
if (ret)
699-
return ret;
701+
drm_dbg_kms(&i915->drm,
702+
"HDCP2 DPCD capability read failed err: %d\n", ret);
700703

701704
ret = intel_dp_hdcp_read_bcaps(aux, i915, &bcaps);
702705
if (ret)

drivers/gpu/drm/i915/display/intel_psr.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,17 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
14221422
return;
14231423
}
14241424

1425+
/*
1426+
* FIXME figure out what is wrong with PSR+bigjoiner and
1427+
* fix it. Presumably something related to the fact that
1428+
* PSR is a transcoder level feature.
1429+
*/
1430+
if (crtc_state->bigjoiner_pipes) {
1431+
drm_dbg_kms(&dev_priv->drm,
1432+
"PSR disabled due to bigjoiner\n");
1433+
return;
1434+
}
1435+
14251436
if (CAN_PANEL_REPLAY(intel_dp))
14261437
crtc_state->has_panel_replay = true;
14271438
else

drivers/gpu/drm/i915/display/intel_vrr.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
117117
const struct drm_display_info *info = &connector->base.display_info;
118118
int vmin, vmax;
119119

120+
/*
121+
* FIXME all joined pipes share the same transcoder.
122+
* Need to account for that during VRR toggle/push/etc.
123+
*/
124+
if (crtc_state->bigjoiner_pipes)
125+
return;
126+
120127
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
121128
return;
122129

drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,14 +1403,17 @@ static void guc_cancel_busyness_worker(struct intel_guc *guc)
14031403
* Trying to pass a 'need_sync' or 'in_reset' flag all the way down through
14041404
* every possible call stack is unfeasible. It would be too intrusive to many
14051405
* areas that really don't care about the GuC backend. However, there is the
1406-
* 'reset_in_progress' flag available, so just use that.
1406+
* I915_RESET_BACKOFF flag and the gt->reset.mutex can be tested for is_locked.
1407+
* So just use those. Note that testing both is required due to the hideously
1408+
* complex nature of the i915 driver's reset code paths.
14071409
*
14081410
* And note that in the case of a reset occurring during driver unload
1409-
* (wedge_on_fini), skipping the cancel in _prepare (when the reset flag is set
1410-
* is fine because there is another cancel in _finish (when the reset flag is
1411-
* not).
1411+
* (wedged_on_fini), skipping the cancel in reset_prepare/reset_fini (when the
1412+
* reset flag/mutex are set) is fine because there is another explicit cancel in
1413+
* intel_guc_submission_fini (when the reset flag/mutex are not).
14121414
*/
1413-
if (guc_to_gt(guc)->uc.reset_in_progress)
1415+
if (mutex_is_locked(&guc_to_gt(guc)->reset.mutex) ||
1416+
test_bit(I915_RESET_BACKOFF, &guc_to_gt(guc)->reset.flags))
14141417
cancel_delayed_work(&guc->timestamp.work);
14151418
else
14161419
cancel_delayed_work_sync(&guc->timestamp.work);
@@ -1424,8 +1427,6 @@ static void __reset_guc_busyness_stats(struct intel_guc *guc)
14241427
unsigned long flags;
14251428
ktime_t unused;
14261429

1427-
guc_cancel_busyness_worker(guc);
1428-
14291430
spin_lock_irqsave(&guc->timestamp.lock, flags);
14301431

14311432
guc_update_pm_timestamp(guc, &unused);
@@ -2004,13 +2005,6 @@ void intel_guc_submission_cancel_requests(struct intel_guc *guc)
20042005

20052006
void intel_guc_submission_reset_finish(struct intel_guc *guc)
20062007
{
2007-
/*
2008-
* Ensure the busyness worker gets cancelled even on a fatal wedge.
2009-
* Note that reset_prepare is not allowed to because it confuses lockdep.
2010-
*/
2011-
if (guc_submission_initialized(guc))
2012-
guc_cancel_busyness_worker(guc);
2013-
20142008
/* Reset called during driver load or during wedge? */
20152009
if (unlikely(!guc_submission_initialized(guc) ||
20162010
!intel_guc_is_fw_running(guc) ||
@@ -2136,6 +2130,7 @@ void intel_guc_submission_fini(struct intel_guc *guc)
21362130
if (!guc->submission_initialized)
21372131
return;
21382132

2133+
guc_fini_engine_stats(guc);
21392134
guc_flush_destroyed_contexts(guc);
21402135
guc_lrc_desc_pool_destroy_v69(guc);
21412136
i915_sched_engine_put(guc->sched_engine);

drivers/gpu/drm/i915/gt/uc/intel_uc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,10 @@ void intel_uc_reset_finish(struct intel_uc *uc)
637637
{
638638
struct intel_guc *guc = &uc->guc;
639639

640+
/*
641+
* NB: The wedge code path results in prepare -> prepare -> finish -> finish.
642+
* So this function is sometimes called with the in-progress flag not set.
643+
*/
640644
uc->reset_in_progress = false;
641645

642646
/* Firmware expected to be running when this function is called */

0 commit comments

Comments
 (0)