Skip to content

Commit 7830643

Browse files
committed
Merge tag 'drm-intel-fixes-2022-02-10' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
- Build fix for non-x86 platforms after remap_io_mmapping changes. (Lucas De Marchi) - Correctly propagate errors during object migration blits. (Thomas Hellström) - Disable DRRS support on HSW/IVB where it is not implemented yet. (Ville Syrjälä) - Correct pipe dbuf BIOS configuration during readout. (Ville Syrjälä) - Properly sanitise BIOS buf configuration on ADL-P+ for !join_mbus cases. (Ville Syrjälä) - Fix oops due to missing stack depot. (Ville Syrjälä) - Workaround broken BIOS DBUF configuration on TGL/RKL. (Ville Syrjälä) Signed-off-by: Dave Airlie <[email protected]> From: Tvrtko Ursulin <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/YgTuYAtpaV3XAGmx@tursulin-mobl2
2 parents df2bb4d + 4e6f551 commit 7830643

File tree

7 files changed

+142
-30
lines changed

7 files changed

+142
-30
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10673,6 +10673,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
1067310673
vlv_wm_sanitize(dev_priv);
1067410674
} else if (DISPLAY_VER(dev_priv) >= 9) {
1067510675
skl_wm_get_hw_state(dev_priv);
10676+
skl_wm_sanitize(dev_priv);
1067610677
} else if (HAS_PCH_SPLIT(dev_priv)) {
1067710678
ilk_wm_get_hw_state(dev_priv);
1067810679
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ intel_drrs_init(struct intel_connector *connector,
405405
struct drm_display_mode *fixed_mode)
406406
{
407407
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
408+
struct intel_encoder *encoder = connector->encoder;
408409
struct drm_display_mode *downclock_mode = NULL;
409410

410411
INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_drrs_downclock_work);
@@ -416,6 +417,13 @@ intel_drrs_init(struct intel_connector *connector,
416417
return NULL;
417418
}
418419

420+
if ((DISPLAY_VER(dev_priv) < 8 && !HAS_GMCH(dev_priv)) &&
421+
encoder->port != PORT_A) {
422+
drm_dbg_kms(&dev_priv->drm,
423+
"DRRS only supported on eDP port A\n");
424+
return NULL;
425+
}
426+
419427
if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
420428
drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
421429
return NULL;

drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -427,11 +427,17 @@ __i915_ttm_move(struct ttm_buffer_object *bo,
427427

428428
if (!IS_ERR(fence))
429429
goto out;
430-
} else if (move_deps) {
431-
int err = i915_deps_sync(move_deps, ctx);
430+
} else {
431+
int err = PTR_ERR(fence);
432+
433+
if (err == -EINTR || err == -ERESTARTSYS || err == -EAGAIN)
434+
return fence;
432435

433-
if (err)
434-
return ERR_PTR(err);
436+
if (move_deps) {
437+
err = i915_deps_sync(move_deps, ctx);
438+
if (err)
439+
return ERR_PTR(err);
440+
}
435441
}
436442

437443
/* Error intercept failed or no accelerated migration to start with */

drivers/gpu/drm/i915/i915_mm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#ifndef __I915_MM_H__
77
#define __I915_MM_H__
88

9+
#include <linux/bug.h>
910
#include <linux/types.h>
1011

1112
struct vm_area_struct;

drivers/gpu/drm/i915/intel_pm.c

Lines changed: 120 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4717,6 +4717,10 @@ static const struct dbuf_slice_conf_entry dg2_allowed_dbufs[] = {
47174717
};
47184718

47194719
static const struct dbuf_slice_conf_entry adlp_allowed_dbufs[] = {
4720+
/*
4721+
* Keep the join_mbus cases first so check_mbus_joined()
4722+
* will prefer them over the !join_mbus cases.
4723+
*/
47204724
{
47214725
.active_pipes = BIT(PIPE_A),
47224726
.dbuf_mask = {
@@ -4731,6 +4735,20 @@ static const struct dbuf_slice_conf_entry adlp_allowed_dbufs[] = {
47314735
},
47324736
.join_mbus = true,
47334737
},
4738+
{
4739+
.active_pipes = BIT(PIPE_A),
4740+
.dbuf_mask = {
4741+
[PIPE_A] = BIT(DBUF_S1) | BIT(DBUF_S2),
4742+
},
4743+
.join_mbus = false,
4744+
},
4745+
{
4746+
.active_pipes = BIT(PIPE_B),
4747+
.dbuf_mask = {
4748+
[PIPE_B] = BIT(DBUF_S3) | BIT(DBUF_S4),
4749+
},
4750+
.join_mbus = false,
4751+
},
47344752
{
47354753
.active_pipes = BIT(PIPE_A) | BIT(PIPE_B),
47364754
.dbuf_mask = {
@@ -4847,13 +4865,14 @@ static bool adlp_check_mbus_joined(u8 active_pipes)
48474865
return check_mbus_joined(active_pipes, adlp_allowed_dbufs);
48484866
}
48494867

4850-
static u8 compute_dbuf_slices(enum pipe pipe, u8 active_pipes,
4868+
static u8 compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus,
48514869
const struct dbuf_slice_conf_entry *dbuf_slices)
48524870
{
48534871
int i;
48544872

48554873
for (i = 0; i < dbuf_slices[i].active_pipes; i++) {
4856-
if (dbuf_slices[i].active_pipes == active_pipes)
4874+
if (dbuf_slices[i].active_pipes == active_pipes &&
4875+
dbuf_slices[i].join_mbus == join_mbus)
48574876
return dbuf_slices[i].dbuf_mask[pipe];
48584877
}
48594878
return 0;
@@ -4864,7 +4883,7 @@ static u8 compute_dbuf_slices(enum pipe pipe, u8 active_pipes,
48644883
* returns correspondent DBuf slice mask as stated in BSpec for particular
48654884
* platform.
48664885
*/
4867-
static u8 icl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes)
4886+
static u8 icl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus)
48684887
{
48694888
/*
48704889
* FIXME: For ICL this is still a bit unclear as prev BSpec revision
@@ -4878,37 +4897,41 @@ static u8 icl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes)
48784897
* still here - we will need it once those additional constraints
48794898
* pop up.
48804899
*/
4881-
return compute_dbuf_slices(pipe, active_pipes, icl_allowed_dbufs);
4900+
return compute_dbuf_slices(pipe, active_pipes, join_mbus,
4901+
icl_allowed_dbufs);
48824902
}
48834903

4884-
static u8 tgl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes)
4904+
static u8 tgl_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus)
48854905
{
4886-
return compute_dbuf_slices(pipe, active_pipes, tgl_allowed_dbufs);
4906+
return compute_dbuf_slices(pipe, active_pipes, join_mbus,
4907+
tgl_allowed_dbufs);
48874908
}
48884909

4889-
static u32 adlp_compute_dbuf_slices(enum pipe pipe, u32 active_pipes)
4910+
static u8 adlp_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus)
48904911
{
4891-
return compute_dbuf_slices(pipe, active_pipes, adlp_allowed_dbufs);
4912+
return compute_dbuf_slices(pipe, active_pipes, join_mbus,
4913+
adlp_allowed_dbufs);
48924914
}
48934915

4894-
static u32 dg2_compute_dbuf_slices(enum pipe pipe, u32 active_pipes)
4916+
static u8 dg2_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbus)
48954917
{
4896-
return compute_dbuf_slices(pipe, active_pipes, dg2_allowed_dbufs);
4918+
return compute_dbuf_slices(pipe, active_pipes, join_mbus,
4919+
dg2_allowed_dbufs);
48974920
}
48984921

4899-
static u8 skl_compute_dbuf_slices(struct intel_crtc *crtc, u8 active_pipes)
4922+
static u8 skl_compute_dbuf_slices(struct intel_crtc *crtc, u8 active_pipes, bool join_mbus)
49004923
{
49014924
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
49024925
enum pipe pipe = crtc->pipe;
49034926

49044927
if (IS_DG2(dev_priv))
4905-
return dg2_compute_dbuf_slices(pipe, active_pipes);
4928+
return dg2_compute_dbuf_slices(pipe, active_pipes, join_mbus);
49064929
else if (IS_ALDERLAKE_P(dev_priv))
4907-
return adlp_compute_dbuf_slices(pipe, active_pipes);
4930+
return adlp_compute_dbuf_slices(pipe, active_pipes, join_mbus);
49084931
else if (DISPLAY_VER(dev_priv) == 12)
4909-
return tgl_compute_dbuf_slices(pipe, active_pipes);
4932+
return tgl_compute_dbuf_slices(pipe, active_pipes, join_mbus);
49104933
else if (DISPLAY_VER(dev_priv) == 11)
4911-
return icl_compute_dbuf_slices(pipe, active_pipes);
4934+
return icl_compute_dbuf_slices(pipe, active_pipes, join_mbus);
49124935
/*
49134936
* For anything else just return one slice yet.
49144937
* Should be extended for other platforms.
@@ -6127,11 +6150,16 @@ skl_compute_ddb(struct intel_atomic_state *state)
61276150
return ret;
61286151
}
61296152

6153+
if (IS_ALDERLAKE_P(dev_priv))
6154+
new_dbuf_state->joined_mbus =
6155+
adlp_check_mbus_joined(new_dbuf_state->active_pipes);
6156+
61306157
for_each_intel_crtc(&dev_priv->drm, crtc) {
61316158
enum pipe pipe = crtc->pipe;
61326159

61336160
new_dbuf_state->slices[pipe] =
6134-
skl_compute_dbuf_slices(crtc, new_dbuf_state->active_pipes);
6161+
skl_compute_dbuf_slices(crtc, new_dbuf_state->active_pipes,
6162+
new_dbuf_state->joined_mbus);
61356163

61366164
if (old_dbuf_state->slices[pipe] == new_dbuf_state->slices[pipe])
61376165
continue;
@@ -6143,9 +6171,6 @@ skl_compute_ddb(struct intel_atomic_state *state)
61436171

61446172
new_dbuf_state->enabled_slices = intel_dbuf_enabled_slices(new_dbuf_state);
61456173

6146-
if (IS_ALDERLAKE_P(dev_priv))
6147-
new_dbuf_state->joined_mbus = adlp_check_mbus_joined(new_dbuf_state->active_pipes);
6148-
61496174
if (old_dbuf_state->enabled_slices != new_dbuf_state->enabled_slices ||
61506175
old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) {
61516176
ret = intel_atomic_serialize_global_state(&new_dbuf_state->base);
@@ -6626,6 +6651,7 @@ void skl_wm_get_hw_state(struct drm_i915_private *dev_priv)
66266651
enum pipe pipe = crtc->pipe;
66276652
unsigned int mbus_offset;
66286653
enum plane_id plane_id;
6654+
u8 slices;
66296655

66306656
skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal);
66316657
crtc_state->wm.skl.raw = crtc_state->wm.skl.optimal;
@@ -6645,19 +6671,22 @@ void skl_wm_get_hw_state(struct drm_i915_private *dev_priv)
66456671
skl_ddb_entry_union(&dbuf_state->ddb[pipe], ddb_uv);
66466672
}
66476673

6648-
dbuf_state->slices[pipe] =
6649-
skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes);
6650-
66516674
dbuf_state->weight[pipe] = intel_crtc_ddb_weight(crtc_state);
66526675

66536676
/*
66546677
* Used for checking overlaps, so we need absolute
66556678
* offsets instead of MBUS relative offsets.
66566679
*/
6657-
mbus_offset = mbus_ddb_offset(dev_priv, dbuf_state->slices[pipe]);
6680+
slices = skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes,
6681+
dbuf_state->joined_mbus);
6682+
mbus_offset = mbus_ddb_offset(dev_priv, slices);
66586683
crtc_state->wm.skl.ddb.start = mbus_offset + dbuf_state->ddb[pipe].start;
66596684
crtc_state->wm.skl.ddb.end = mbus_offset + dbuf_state->ddb[pipe].end;
66606685

6686+
/* The slices actually used by the planes on the pipe */
6687+
dbuf_state->slices[pipe] =
6688+
skl_ddb_dbuf_slice_mask(dev_priv, &crtc_state->wm.skl.ddb);
6689+
66616690
drm_dbg_kms(&dev_priv->drm,
66626691
"[CRTC:%d:%s] dbuf slices 0x%x, ddb (%d - %d), active pipes 0x%x, mbus joined: %s\n",
66636692
crtc->base.base.id, crtc->base.name,
@@ -6669,6 +6698,74 @@ void skl_wm_get_hw_state(struct drm_i915_private *dev_priv)
66696698
dbuf_state->enabled_slices = dev_priv->dbuf.enabled_slices;
66706699
}
66716700

6701+
static bool skl_dbuf_is_misconfigured(struct drm_i915_private *i915)
6702+
{
6703+
const struct intel_dbuf_state *dbuf_state =
6704+
to_intel_dbuf_state(i915->dbuf.obj.state);
6705+
struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
6706+
struct intel_crtc *crtc;
6707+
6708+
for_each_intel_crtc(&i915->drm, crtc) {
6709+
const struct intel_crtc_state *crtc_state =
6710+
to_intel_crtc_state(crtc->base.state);
6711+
6712+
entries[crtc->pipe] = crtc_state->wm.skl.ddb;
6713+
}
6714+
6715+
for_each_intel_crtc(&i915->drm, crtc) {
6716+
const struct intel_crtc_state *crtc_state =
6717+
to_intel_crtc_state(crtc->base.state);
6718+
u8 slices;
6719+
6720+
slices = skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes,
6721+
dbuf_state->joined_mbus);
6722+
if (dbuf_state->slices[crtc->pipe] & ~slices)
6723+
return true;
6724+
6725+
if (skl_ddb_allocation_overlaps(&crtc_state->wm.skl.ddb, entries,
6726+
I915_MAX_PIPES, crtc->pipe))
6727+
return true;
6728+
}
6729+
6730+
return false;
6731+
}
6732+
6733+
void skl_wm_sanitize(struct drm_i915_private *i915)
6734+
{
6735+
struct intel_crtc *crtc;
6736+
6737+
/*
6738+
* On TGL/RKL (at least) the BIOS likes to assign the planes
6739+
* to the wrong DBUF slices. This will cause an infinite loop
6740+
* in skl_commit_modeset_enables() as it can't find a way to
6741+
* transition between the old bogus DBUF layout to the new
6742+
* proper DBUF layout without DBUF allocation overlaps between
6743+
* the planes (which cannot be allowed or else the hardware
6744+
* may hang). If we detect a bogus DBUF layout just turn off
6745+
* all the planes so that skl_commit_modeset_enables() can
6746+
* simply ignore them.
6747+
*/
6748+
if (!skl_dbuf_is_misconfigured(i915))
6749+
return;
6750+
6751+
drm_dbg_kms(&i915->drm, "BIOS has misprogrammed the DBUF, disabling all planes\n");
6752+
6753+
for_each_intel_crtc(&i915->drm, crtc) {
6754+
struct intel_plane *plane = to_intel_plane(crtc->base.primary);
6755+
const struct intel_plane_state *plane_state =
6756+
to_intel_plane_state(plane->base.state);
6757+
struct intel_crtc_state *crtc_state =
6758+
to_intel_crtc_state(crtc->base.state);
6759+
6760+
if (plane_state->uapi.visible)
6761+
intel_plane_disable_noatomic(crtc, plane);
6762+
6763+
drm_WARN_ON(&i915->drm, crtc_state->active_planes != 0);
6764+
6765+
memset(&crtc_state->wm.skl.ddb, 0, sizeof(crtc_state->wm.skl.ddb));
6766+
}
6767+
}
6768+
66726769
static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc)
66736770
{
66746771
struct drm_device *dev = crtc->base.dev;

drivers/gpu/drm/i915/intel_pm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
4747
struct skl_pipe_wm *out);
4848
void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
4949
void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
50+
void skl_wm_sanitize(struct drm_i915_private *dev_priv);
5051
bool intel_can_enable_sagv(struct drm_i915_private *dev_priv,
5152
const struct intel_bw_state *bw_state);
5253
void intel_sagv_pre_plane_update(struct intel_atomic_state *state);

drivers/gpu/drm/i915/intel_runtime_pm.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ static noinline depot_stack_handle_t __save_depot_stack(void)
6868
static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm)
6969
{
7070
spin_lock_init(&rpm->debug.lock);
71-
72-
if (rpm->available)
73-
stack_depot_init();
71+
stack_depot_init();
7472
}
7573

7674
static noinline depot_stack_handle_t

0 commit comments

Comments
 (0)