Commit 51af5563 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-fixes-2023-12-13' of...

Merge tag 'drm-intel-fixes-2023-12-13' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes

drm/i915 fixes for v6.7-rc6:
- Fix selftest engine reset count storage for multi-tile
- Fix out-of-bounds reads for engine reset counts
- Fix ADL+ remapped stride with CCS
- Fix intel_atomic_setup_scalers() plane_state handling
- Fix ADL+ tiled plane stride when the POT stride is smaller than the original
- Fix eDP 1.4 rate select method link configuration
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/871qbqw4rw.fsf@intel.com
parents 2fda6174 e6861d82
......@@ -650,19 +650,30 @@ intel_dp_update_link_bw_set(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
u8 link_bw, u8 rate_select)
{
u8 link_config[2];
u8 lane_count = crtc_state->lane_count;
/* Write the link configuration data */
link_config[0] = link_bw;
link_config[1] = crtc_state->lane_count;
if (crtc_state->enhanced_framing)
link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2);
lane_count |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
if (link_bw) {
/* DP and eDP v1.3 and earlier link bw set method. */
u8 link_config[] = { link_bw, lane_count };
/* eDP 1.4 rate select method. */
if (!link_bw)
drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET,
&rate_select, 1);
drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config,
ARRAY_SIZE(link_config));
} else {
/*
* eDP v1.4 and later link rate set method.
*
* eDP v1.4x sinks shall ignore DP_LINK_RATE_SET if
* DP_LINK_BW_SET is set. Avoid writing DP_LINK_BW_SET.
*
* eDP v1.5 sinks allow choosing either, and the last choice
* shall be active.
*/
drm_dp_dpcd_writeb(&intel_dp->aux, DP_LANE_COUNT_SET, lane_count);
drm_dp_dpcd_writeb(&intel_dp->aux, DP_LINK_RATE_SET, rate_select);
}
}
/*
......
......@@ -1374,7 +1374,8 @@ plane_view_scanout_stride(const struct intel_framebuffer *fb, int color_plane,
struct drm_i915_private *i915 = to_i915(fb->base.dev);
unsigned int stride_tiles;
if (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14)
if ((IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14) &&
src_stride_tiles < dst_stride_tiles)
stride_tiles = src_stride_tiles;
else
stride_tiles = dst_stride_tiles;
......@@ -1501,8 +1502,20 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
size += remap_info->size;
} else {
unsigned int dst_stride = plane_view_dst_stride_tiles(fb, color_plane,
remap_info->width);
unsigned int dst_stride;
/*
* The hardware automagically calculates the CCS AUX surface
* stride from the main surface stride so can't really remap a
* smaller subset (unless we'd remap in whole AUX page units).
*/
if (intel_fb_needs_pot_stride_remap(fb) &&
intel_fb_is_ccs_modifier(fb->base.modifier))
dst_stride = remap_info->src_stride;
else
dst_stride = remap_info->width;
dst_stride = plane_view_dst_stride_tiles(fb, color_plane, dst_stride);
assign_chk_ovf(i915, remap_info->dst_stride, dst_stride);
color_plane_info->mapping_stride = dst_stride *
......
......@@ -504,7 +504,6 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
{
struct drm_plane *plane = NULL;
struct intel_plane *intel_plane;
struct intel_plane_state *plane_state = NULL;
struct intel_crtc_scaler_state *scaler_state =
&crtc_state->scaler_state;
struct drm_atomic_state *drm_state = crtc_state->uapi.state;
......@@ -536,6 +535,7 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
/* walkthrough scaler_users bits and start assigning scalers */
for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) {
struct intel_plane_state *plane_state = NULL;
int *scaler_id;
const char *name;
int idx, ret;
......
......@@ -1293,7 +1293,7 @@ int __intel_engine_reset_bh(struct intel_engine_cs *engine, const char *msg)
if (msg)
drm_notice(&engine->i915->drm,
"Resetting %s for %s\n", engine->name, msg);
atomic_inc(&engine->i915->gpu_error.reset_engine_count[engine->uabi_class]);
i915_increase_reset_engine_count(&engine->i915->gpu_error, engine);
ret = intel_gt_reset_engine(engine);
if (ret) {
......
......@@ -5001,7 +5001,8 @@ static void capture_error_state(struct intel_guc *guc,
if (match) {
intel_engine_set_hung_context(e, ce);
engine_mask |= e->mask;
atomic_inc(&i915->gpu_error.reset_engine_count[e->uabi_class]);
i915_increase_reset_engine_count(&i915->gpu_error,
e);
}
}
......@@ -5013,7 +5014,7 @@ static void capture_error_state(struct intel_guc *guc,
} else {
intel_engine_set_hung_context(ce->engine, ce);
engine_mask = ce->engine->mask;
atomic_inc(&i915->gpu_error.reset_engine_count[ce->engine->uabi_class]);
i915_increase_reset_engine_count(&i915->gpu_error, ce->engine);
}
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
......
......@@ -16,6 +16,7 @@
#include "display/intel_display_device.h"
#include "gt/intel_engine.h"
#include "gt/intel_engine_types.h"
#include "gt/intel_gt_types.h"
#include "gt/uc/intel_uc_fw.h"
......@@ -232,7 +233,7 @@ struct i915_gpu_error {
atomic_t reset_count;
/** Number of times an engine has been reset */
atomic_t reset_engine_count[I915_NUM_ENGINES];
atomic_t reset_engine_count[MAX_ENGINE_CLASS];
};
struct drm_i915_error_state_buf {
......@@ -255,7 +256,14 @@ static inline u32 i915_reset_count(struct i915_gpu_error *error)
static inline u32 i915_reset_engine_count(struct i915_gpu_error *error,
const struct intel_engine_cs *engine)
{
return atomic_read(&error->reset_engine_count[engine->uabi_class]);
return atomic_read(&error->reset_engine_count[engine->class]);
}
static inline void
i915_increase_reset_engine_count(struct i915_gpu_error *error,
const struct intel_engine_cs *engine)
{
atomic_inc(&error->reset_engine_count[engine->class]);
}
#define CORE_DUMP_FLAG_NONE 0x0
......
......@@ -37,8 +37,9 @@ int igt_live_test_begin(struct igt_live_test *t,
}
for_each_engine(engine, gt, id)
t->reset_engine[id] =
i915_reset_engine_count(&i915->gpu_error, engine);
t->reset_engine[i][id] =
i915_reset_engine_count(&i915->gpu_error,
engine);
}
t->reset_global = i915_reset_count(&i915->gpu_error);
......@@ -66,14 +67,14 @@ int igt_live_test_end(struct igt_live_test *t)
for_each_gt(gt, i915, i) {
for_each_engine(engine, gt, id) {
if (t->reset_engine[id] ==
if (t->reset_engine[i][id] ==
i915_reset_engine_count(&i915->gpu_error, engine))
continue;
gt_err(gt, "%s(%s): engine '%s' was reset %d times!\n",
t->func, t->name, engine->name,
i915_reset_engine_count(&i915->gpu_error, engine) -
t->reset_engine[id]);
t->reset_engine[i][id]);
return -EIO;
}
}
......
......@@ -7,6 +7,7 @@
#ifndef IGT_LIVE_TEST_H
#define IGT_LIVE_TEST_H
#include "gt/intel_gt_defines.h" /* for I915_MAX_GT */
#include "gt/intel_engine.h" /* for I915_NUM_ENGINES */
struct drm_i915_private;
......@@ -17,7 +18,7 @@ struct igt_live_test {
const char *name;
unsigned int reset_global;
unsigned int reset_engine[I915_NUM_ENGINES];
unsigned int reset_engine[I915_MAX_GT][I915_NUM_ENGINES];
};
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment