Skip to content

Commit f730f39

Browse files
committed
Merge tag 'drm-intel-next-fixes-2021-02-18' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
- Restrict DRM_I915_DEBUG to developer builds (Chris) - Fix return and error codes (Dan) - Suspend/Resume fix (Chris) - Disable atomics in L3 for gen9 (Chris) - Flush before changing register state (Chris) - Fix for GLK's HDMI (Ville) - Fix ILK+'s plane strides with Xtiling (Ville) - Correct surface base address for renderclear (Chris) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/YC7uQY1kt6w0tRp+@intel.com
2 parents 4f8ad40 + 81ce8f0 commit f730f39

16 files changed

Lines changed: 115 additions & 60 deletions

drivers/gpu/drm/i915/Kconfig.debug

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ config DRM_I915_WERROR
1919
config DRM_I915_DEBUG
2020
bool "Enable additional driver debugging"
2121
depends on DRM_I915
22+
depends on EXPERT # only for developers
23+
depends on !COMPILE_TEST # never built by robots
2224
select DEBUG_FS
2325
select PREEMPT_COUNT
2426
select I2C_CHARDEV

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,33 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
255255
else
256256
offset = 0;
257257

258+
/*
259+
* When using an X-tiled surface the plane starts to
260+
* misbehave if the x offset + width exceeds the stride.
261+
* hsw/bdw: underrun galore
262+
* ilk/snb/ivb: wrap to the next tile row mid scanout
263+
* i965/g4x: so far appear immune to this
264+
* vlv/chv: TODO check
265+
*
266+
* Linear surfaces seem to work just fine, even on hsw/bdw
267+
* despite them not using the linear offset anymore.
268+
*/
269+
if (INTEL_GEN(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) {
270+
u32 alignment = intel_surf_alignment(fb, 0);
271+
int cpp = fb->format->cpp[0];
272+
273+
while ((src_x + src_w) * cpp > plane_state->color_plane[0].stride) {
274+
if (offset == 0) {
275+
drm_dbg_kms(&dev_priv->drm,
276+
"Unable to find suitable display surface offset due to X-tiling\n");
277+
return -EINVAL;
278+
}
279+
280+
offset = intel_plane_adjust_aligned_offset(&src_x, &src_y, plane_state, 0,
281+
offset, offset - alignment);
282+
}
283+
}
284+
258285
/*
259286
* Put the final coordinates back so that the src
260287
* coordinate checks will see the right values.

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,8 +1322,8 @@ static bool has_async_flips(struct drm_i915_private *i915)
13221322
return INTEL_GEN(i915) >= 5;
13231323
}
13241324

1325-
static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
1326-
int color_plane)
1325+
unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
1326+
int color_plane)
13271327
{
13281328
struct drm_i915_private *dev_priv = to_i915(fb->dev);
13291329

@@ -1590,10 +1590,10 @@ static u32 intel_adjust_aligned_offset(int *x, int *y,
15901590
* Adjust the tile offset by moving the difference into
15911591
* the x/y offsets.
15921592
*/
1593-
static u32 intel_plane_adjust_aligned_offset(int *x, int *y,
1594-
const struct intel_plane_state *state,
1595-
int color_plane,
1596-
u32 old_offset, u32 new_offset)
1593+
u32 intel_plane_adjust_aligned_offset(int *x, int *y,
1594+
const struct intel_plane_state *state,
1595+
int color_plane,
1596+
u32 old_offset, u32 new_offset)
15971597
{
15981598
return intel_adjust_aligned_offset(x, y, state->hw.fb, color_plane,
15991599
state->hw.rotation,

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,12 @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state);
653653
struct intel_encoder *
654654
intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
655655
const struct intel_crtc_state *crtc_state);
656+
unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
657+
int color_plane);
658+
u32 intel_plane_adjust_aligned_offset(int *x, int *y,
659+
const struct intel_plane_state *state,
660+
int color_plane,
661+
u32 old_offset, u32 new_offset);
656662

657663
/* modesetting */
658664
void intel_modeset_init_hw(struct drm_i915_private *i915);

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2218,7 +2218,11 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi,
22182218
has_hdmi_sink))
22192219
return MODE_CLOCK_HIGH;
22202220

2221-
/* BXT DPLL can't generate 223-240 MHz */
2221+
/* GLK DPLL can't generate 446-480 MHz */
2222+
if (IS_GEMINILAKE(dev_priv) && clock > 446666 && clock < 480000)
2223+
return MODE_CLOCK_RANGE;
2224+
2225+
/* BXT/GLK DPLL can't generate 223-240 MHz */
22222226
if (IS_GEN9_LP(dev_priv) && clock > 223333 && clock < 240000)
22232227
return MODE_CLOCK_RANGE;
22242228

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,47 @@ void i915_gem_suspend_late(struct drm_i915_private *i915)
8585
wbinvd_on_all_cpus();
8686
}
8787

88+
int i915_gem_freeze(struct drm_i915_private *i915)
89+
{
90+
/* Discard all purgeable objects, let userspace recover those as
91+
* required after resuming.
92+
*/
93+
i915_gem_shrink_all(i915);
94+
95+
return 0;
96+
}
97+
98+
int i915_gem_freeze_late(struct drm_i915_private *i915)
99+
{
100+
struct drm_i915_gem_object *obj;
101+
intel_wakeref_t wakeref;
102+
103+
/*
104+
* Called just before we write the hibernation image.
105+
*
106+
* We need to update the domain tracking to reflect that the CPU
107+
* will be accessing all the pages to create and restore from the
108+
* hibernation, and so upon restoration those pages will be in the
109+
* CPU domain.
110+
*
111+
* To make sure the hibernation image contains the latest state,
112+
* we update that state just before writing out the image.
113+
*
114+
* To try and reduce the hibernation image, we manually shrink
115+
* the objects as well, see i915_gem_freeze()
116+
*/
117+
118+
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
119+
i915_gem_shrink(i915, -1UL, NULL, ~0);
120+
i915_gem_drain_freed_objects(i915);
121+
122+
wbinvd_on_all_cpus();
123+
list_for_each_entry(obj, &i915->mm.shrink_list, mm.link)
124+
__start_cpu_write(obj);
125+
126+
return 0;
127+
}
128+
88129
void i915_gem_resume(struct drm_i915_private *i915)
89130
{
90131
GEM_TRACE("%s\n", dev_name(i915->drm.dev));

drivers/gpu/drm/i915/gem/i915_gem_pm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ void i915_gem_idle_work_handler(struct work_struct *work);
1919
void i915_gem_suspend(struct drm_i915_private *i915);
2020
void i915_gem_suspend_late(struct drm_i915_private *i915);
2121

22+
int i915_gem_freeze(struct drm_i915_private *i915);
23+
int i915_gem_freeze_late(struct drm_i915_private *i915);
24+
2225
#endif /* __I915_GEM_PM_H__ */

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

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -753,22 +753,18 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *i915,
753753
mutex_lock(&i915->mm.stolen_lock);
754754
ret = drm_mm_reserve_node(&i915->mm.stolen, stolen);
755755
mutex_unlock(&i915->mm.stolen_lock);
756-
if (ret) {
757-
obj = ERR_PTR(ret);
756+
if (ret)
758757
goto err_free;
759-
}
760758

761759
obj = i915_gem_object_alloc();
762760
if (!obj) {
763-
obj = ERR_PTR(-ENOMEM);
761+
ret = -ENOMEM;
764762
goto err_stolen;
765763
}
766764

767765
ret = __i915_gem_object_create_stolen(mem, obj, stolen);
768-
if (ret) {
769-
obj = ERR_PTR(ret);
766+
if (ret)
770767
goto err_object_free;
771-
}
772768

773769
i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
774770
return obj;
@@ -779,7 +775,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *i915,
779775
i915_gem_stolen_remove_node(i915, stolen);
780776
err_free:
781777
kfree(stolen);
782-
return obj;
778+
return ERR_PTR(ret);
783779
}
784780

785781
bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj)

drivers/gpu/drm/i915/gt/gen7_renderclear.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ gen7_emit_state_base_address(struct batch_chunk *batch,
240240
/* general */
241241
*cs++ = batch_addr(batch) | BASE_ADDRESS_MODIFY;
242242
/* surface */
243-
*cs++ = batch_addr(batch) | surface_state_base | BASE_ADDRESS_MODIFY;
243+
*cs++ = (batch_addr(batch) + surface_state_base) | BASE_ADDRESS_MODIFY;
244244
/* dynamic */
245245
*cs++ = batch_addr(batch) | BASE_ADDRESS_MODIFY;
246246
/* indirect */
@@ -393,6 +393,7 @@ static void emit_batch(struct i915_vma * const vma,
393393
desc_count);
394394

395395
/* Reset inherited context registers */
396+
gen7_emit_pipeline_flush(&cmds);
396397
gen7_emit_pipeline_invalidate(&cmds);
397398
batch_add(&cmds, MI_LOAD_REGISTER_IMM(2));
398399
batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_0_GEN7));

drivers/gpu/drm/i915/gt/intel_workarounds.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,6 +1834,14 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
18341834
wa_write_or(wal,
18351835
GEN8_L3SQCREG4,
18361836
GEN8_LQSC_FLUSH_COHERENT_LINES);
1837+
1838+
/* Disable atomics in L3 to prevent unrecoverable hangs */
1839+
wa_write_clr_set(wal, GEN9_SCRATCH_LNCF1,
1840+
GEN9_LNCF_NONIA_COHERENT_ATOMICS_ENABLE, 0);
1841+
wa_write_clr_set(wal, GEN8_L3SQCREG4,
1842+
GEN8_LQSQ_NONIA_COHERENT_ATOMICS_ENABLE, 0);
1843+
wa_write_clr_set(wal, GEN9_SCRATCH1,
1844+
EVICTION_PERF_FIX_ENABLE, 0);
18371845
}
18381846

18391847
if (IS_HASWELL(i915)) {

0 commit comments

Comments
 (0)