Commit b2268e26 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-fixes-2022-12-01' of...

Merge tag 'drm-intel-next-fixes-2022-12-01' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

- Multi-cast register fix (Matt)
- Fix workarounds on gen2-3 (Tvrtko)
- Bigjoiner fix (Ville)
- Make Guc default_list a const data (Jani)
- Acquire forcewake before uncore read (Umesh)
- Selftest fix (Umesh)
- HuC related fixes (Daniele)
- Fix some incorrect return values (Janusz)
- Fix a memory leak in bios related code (Xia)
- Fix VBT send packet port selection (Mikko)
- DG2's DMC fix bump for Register noclaims and few restore (Gustavo)
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Y4jZBRw9KvlKgkr6@intel.com
parents 077bd800 7d579eff
......@@ -414,7 +414,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
ptrs->lvds_entries++;
if (size != 0 || ptrs->lvds_entries != 3) {
kfree(ptrs);
kfree(ptrs_block);
return NULL;
}
......
......@@ -3733,12 +3733,16 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,
static u8 bigjoiner_pipes(struct drm_i915_private *i915)
{
u8 pipes;
if (DISPLAY_VER(i915) >= 12)
return BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D);
pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D);
else if (DISPLAY_VER(i915) >= 11)
return BIT(PIPE_B) | BIT(PIPE_C);
pipes = BIT(PIPE_B) | BIT(PIPE_C);
else
return 0;
pipes = 0;
return pipes & RUNTIME_INFO(i915)->pipe_mask;
}
static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,
......
......@@ -52,8 +52,8 @@
#define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE
#define DG2_DMC_PATH DMC_PATH(dg2, 2, 07)
#define DG2_DMC_VERSION_REQUIRED DMC_VERSION(2, 07)
#define DG2_DMC_PATH DMC_PATH(dg2, 2, 08)
#define DG2_DMC_VERSION_REQUIRED DMC_VERSION(2, 8)
MODULE_FIRMWARE(DG2_DMC_PATH);
#define ADLP_DMC_PATH DMC_PATH(adlp, 2, 16)
......
......@@ -137,9 +137,9 @@ static enum port intel_dsi_seq_port_to_port(struct intel_dsi *intel_dsi,
return ffs(intel_dsi->ports) - 1;
if (seq_port) {
if (intel_dsi->ports & PORT_B)
if (intel_dsi->ports & BIT(PORT_B))
return PORT_B;
else if (intel_dsi->ports & PORT_C)
else if (intel_dsi->ports & BIT(PORT_C))
return PORT_C;
}
......
......@@ -677,8 +677,13 @@ int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout)
return -EINTR;
}
return timeout ? timeout : intel_uc_wait_for_idle(&gt->uc,
remaining_timeout);
if (timeout)
return timeout;
if (remaining_timeout < 0)
remaining_timeout = 0;
return intel_uc_wait_for_idle(&gt->uc, remaining_timeout);
}
int intel_gt_init(struct intel_gt *gt)
......@@ -1035,9 +1040,9 @@ get_reg_and_bit(const struct intel_engine_cs *engine, const bool gen8,
static int wait_for_invalidate(struct intel_gt *gt, struct reg_and_bit rb)
{
if (GRAPHICS_VER_FULL(gt->i915) >= IP_VER(12, 50))
return intel_gt_mcr_wait_for_reg_fw(gt, rb.mcr_reg, rb.bit, 0,
TLB_INVAL_TIMEOUT_US,
TLB_INVAL_TIMEOUT_MS);
return intel_gt_mcr_wait_for_reg(gt, rb.mcr_reg, rb.bit, 0,
TLB_INVAL_TIMEOUT_US,
TLB_INVAL_TIMEOUT_MS);
else
return __intel_wait_for_register_fw(gt->uncore, rb.reg, rb.bit, 0,
TLB_INVAL_TIMEOUT_US,
......
......@@ -730,17 +730,19 @@ void intel_gt_mcr_get_ss_steering(struct intel_gt *gt, unsigned int dss,
*
* Return: 0 if the register matches the desired condition, or -ETIMEDOUT.
*/
int intel_gt_mcr_wait_for_reg_fw(struct intel_gt *gt,
i915_mcr_reg_t reg,
u32 mask,
u32 value,
unsigned int fast_timeout_us,
unsigned int slow_timeout_ms)
int intel_gt_mcr_wait_for_reg(struct intel_gt *gt,
i915_mcr_reg_t reg,
u32 mask,
u32 value,
unsigned int fast_timeout_us,
unsigned int slow_timeout_ms)
{
u32 reg_value = 0;
#define done (((reg_value = intel_gt_mcr_read_any_fw(gt, reg)) & mask) == value)
int ret;
lockdep_assert_not_held(&gt->uncore->lock);
#define done ((intel_gt_mcr_read_any(gt, reg) & mask) == value)
/* Catch any overuse of this function */
might_sleep_if(slow_timeout_ms);
GEM_BUG_ON(fast_timeout_us > 20000);
......
......@@ -37,12 +37,12 @@ void intel_gt_mcr_report_steering(struct drm_printer *p, struct intel_gt *gt,
void intel_gt_mcr_get_ss_steering(struct intel_gt *gt, unsigned int dss,
unsigned int *group, unsigned int *instance);
int intel_gt_mcr_wait_for_reg_fw(struct intel_gt *gt,
i915_mcr_reg_t reg,
u32 mask,
u32 value,
unsigned int fast_timeout_us,
unsigned int slow_timeout_ms);
int intel_gt_mcr_wait_for_reg(struct intel_gt *gt,
i915_mcr_reg_t reg,
u32 mask,
u32 value,
unsigned int fast_timeout_us,
unsigned int slow_timeout_ms);
/*
* Helper for for_each_ss_steering loop. On pre-Xe_HP platforms, subslice
......
......@@ -199,7 +199,7 @@ out_active: spin_lock(&timelines->lock);
if (remaining_timeout)
*remaining_timeout = timeout;
return active_count ? timeout : 0;
return active_count ? timeout ?: -ETIME : 0;
}
static void retire_work_handler(struct work_struct *work)
......
......@@ -3011,7 +3011,7 @@ general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_li
static void
engine_init_workarounds(struct intel_engine_cs *engine, struct i915_wa_list *wal)
{
if (I915_SELFTEST_ONLY(GRAPHICS_VER(engine->i915) < 4))
if (GRAPHICS_VER(engine->i915) < 4)
return;
engine_fake_wa_init(engine, wal);
......@@ -3036,9 +3036,6 @@ void intel_engine_init_workarounds(struct intel_engine_cs *engine)
{
struct i915_wa_list *wal = &engine->wa_list;
if (GRAPHICS_VER(engine->i915) < 4)
return;
wa_init_start(wal, engine->gt, "engine", engine->name);
engine_init_workarounds(engine, wal);
wa_init_finish(wal);
......
......@@ -317,7 +317,7 @@ static int live_engine_busy_stats(void *arg)
ENGINE_TRACE(engine, "measuring busy time\n");
preempt_disable();
de = intel_engine_get_busy_time(engine, &t[0]);
mdelay(10);
mdelay(100);
de = ktime_sub(intel_engine_get_busy_time(engine, &t[1]), de);
preempt_enable();
dt = ktime_sub(t[1], t[0]);
......
......@@ -170,7 +170,7 @@ static const struct __guc_mmio_reg_descr empty_regs_list[] = {
}
/* List of lists */
static struct __guc_mmio_reg_descr_group default_lists[] = {
static const struct __guc_mmio_reg_descr_group default_lists[] = {
MAKE_REGLIST(default_global_regs, PF, GLOBAL, 0),
MAKE_REGLIST(default_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS),
MAKE_REGLIST(xe_lpd_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_RENDER_CLASS),
......
......@@ -211,6 +211,30 @@ void intel_huc_unregister_gsc_notifier(struct intel_huc *huc, struct bus_type *b
huc->delayed_load.nb.notifier_call = NULL;
}
static void delayed_huc_load_init(struct intel_huc *huc)
{
/*
* Initialize fence to be complete as this is expected to be complete
* unless there is a delayed HuC load in progress.
*/
i915_sw_fence_init(&huc->delayed_load.fence,
sw_fence_dummy_notify);
i915_sw_fence_commit(&huc->delayed_load.fence);
hrtimer_init(&huc->delayed_load.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
huc->delayed_load.timer.function = huc_delayed_load_timer_callback;
}
static void delayed_huc_load_fini(struct intel_huc *huc)
{
/*
* the fence is initialized in init_early, so we need to clean it up
* even if HuC loading is off.
*/
delayed_huc_load_complete(huc);
i915_sw_fence_fini(&huc->delayed_load.fence);
}
static bool vcs_supported(struct intel_gt *gt)
{
intel_engine_mask_t mask = gt->info.engine_mask;
......@@ -241,6 +265,15 @@ void intel_huc_init_early(struct intel_huc *huc)
intel_uc_fw_init_early(&huc->fw, INTEL_UC_FW_TYPE_HUC);
/*
* we always init the fence as already completed, even if HuC is not
* supported. This way we don't have to distinguish between HuC not
* supported/disabled or already loaded, and can focus on if the load
* is currently in progress (fence not complete) or not, which is what
* we care about for stalling userspace submissions.
*/
delayed_huc_load_init(huc);
if (!vcs_supported(gt)) {
intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED);
return;
......@@ -255,17 +288,6 @@ void intel_huc_init_early(struct intel_huc *huc)
huc->status.mask = HUC_FW_VERIFIED;
huc->status.value = HUC_FW_VERIFIED;
}
/*
* Initialize fence to be complete as this is expected to be complete
* unless there is a delayed HuC reload in progress.
*/
i915_sw_fence_init(&huc->delayed_load.fence,
sw_fence_dummy_notify);
i915_sw_fence_commit(&huc->delayed_load.fence);
hrtimer_init(&huc->delayed_load.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
huc->delayed_load.timer.function = huc_delayed_load_timer_callback;
}
#define HUC_LOAD_MODE_STRING(x) (x ? "GSC" : "legacy")
......@@ -329,13 +351,14 @@ int intel_huc_init(struct intel_huc *huc)
void intel_huc_fini(struct intel_huc *huc)
{
if (!intel_uc_fw_is_loadable(&huc->fw))
return;
delayed_huc_load_complete(huc);
/*
* the fence is initialized in init_early, so we need to clean it up
* even if HuC loading is off.
*/
delayed_huc_load_fini(huc);
i915_sw_fence_fini(&huc->delayed_load.fence);
intel_uc_fw_fini(&huc->fw);
if (intel_uc_fw_is_loadable(&huc->fw))
intel_uc_fw_fini(&huc->fw);
}
void intel_huc_suspend(struct intel_huc *huc)
......
......@@ -722,6 +722,7 @@ int intel_uc_runtime_resume(struct intel_uc *uc)
static const struct intel_uc_ops uc_ops_off = {
.init_hw = __uc_check_hw,
.fini = __uc_fini, /* to clean-up the init_early initialization */
};
static const struct intel_uc_ops uc_ops_on = {
......
......@@ -382,20 +382,6 @@ __uncore_write(write_notrace, 32, l, false)
*/
__uncore_read(read64, 64, q, true)
static inline u64
intel_uncore_read64_2x32(struct intel_uncore *uncore,
i915_reg_t lower_reg, i915_reg_t upper_reg)
{
u32 upper, lower, old_upper, loop = 0;
upper = intel_uncore_read(uncore, upper_reg);
do {
old_upper = upper;
lower = intel_uncore_read(uncore, lower_reg);
upper = intel_uncore_read(uncore, upper_reg);
} while (upper != old_upper && loop++ < 2);
return (u64)upper << 32 | lower;
}
#define intel_uncore_posting_read(...) ((void)intel_uncore_read_notrace(__VA_ARGS__))
#define intel_uncore_posting_read16(...) ((void)intel_uncore_read16_notrace(__VA_ARGS__))
......@@ -455,6 +441,36 @@ static inline void intel_uncore_rmw_fw(struct intel_uncore *uncore,
intel_uncore_write_fw(uncore, reg, val);
}
static inline u64
intel_uncore_read64_2x32(struct intel_uncore *uncore,
i915_reg_t lower_reg, i915_reg_t upper_reg)
{
u32 upper, lower, old_upper, loop = 0;
enum forcewake_domains fw_domains;
unsigned long flags;
fw_domains = intel_uncore_forcewake_for_reg(uncore, lower_reg,
FW_REG_READ);
fw_domains |= intel_uncore_forcewake_for_reg(uncore, upper_reg,
FW_REG_READ);
spin_lock_irqsave(&uncore->lock, flags);
intel_uncore_forcewake_get__locked(uncore, fw_domains);
upper = intel_uncore_read_fw(uncore, upper_reg);
do {
old_upper = upper;
lower = intel_uncore_read_fw(uncore, lower_reg);
upper = intel_uncore_read_fw(uncore, upper_reg);
} while (upper != old_upper && loop++ < 2);
intel_uncore_forcewake_put__locked(uncore, fw_domains);
spin_unlock_irqrestore(&uncore->lock, flags);
return (u64)upper << 32 | lower;
}
static inline int intel_uncore_write_and_verify(struct intel_uncore *uncore,
i915_reg_t reg, u32 val,
u32 mask, u32 expected_val)
......
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