mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 14:21:47 +00:00
Merge tag 'drm-intel-next-fixes-2023-11-08' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
drm/i915 fixes for v6.7-rc1: - Fix null dereference when perf interface is not available - Fix a -Wstringop-overflow warning - Fix a -Wformat-truncation warning in intel_tc_port_init - Flush WC GGTT only on required platforms - Fix MTL HBR3 rate support on C10 phy and eDP - Fix MTL notify_guc for multi-GT - Bump GLK CDCLK frequency when driving multiple pipes - Fix potential spectre vulnerability Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> From: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/878r78xrxd.fsf@intel.com
This commit is contained in:
commit
0b336ec076
@ -2750,6 +2750,18 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
|
||||
for_each_pipe(dev_priv, pipe)
|
||||
min_cdclk = max(cdclk_state->min_cdclk[pipe], min_cdclk);
|
||||
|
||||
/*
|
||||
* Avoid glk_force_audio_cdclk() causing excessive screen
|
||||
* blinking when multiple pipes are active by making sure
|
||||
* CDCLK frequency is always high enough for audio. With a
|
||||
* single active pipe we can always change CDCLK frequency
|
||||
* by changing the cd2x divider (see glk_cdclk_table[]) and
|
||||
* thus a full modeset won't be needed then.
|
||||
*/
|
||||
if (IS_GEMINILAKE(dev_priv) && cdclk_state->active_pipes &&
|
||||
!is_power_of_2(cdclk_state->active_pipes))
|
||||
min_cdclk = max(2 * 96000, min_cdclk);
|
||||
|
||||
if (min_cdclk > dev_priv->display.cdclk.max_cdclk_freq) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"required cdclk (%d kHz) exceeds max (%d kHz)\n",
|
||||
|
@ -430,7 +430,7 @@ static int mtl_max_source_rate(struct intel_dp *intel_dp)
|
||||
enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
|
||||
|
||||
if (intel_is_c10phy(i915, phy))
|
||||
return intel_dp_is_edp(intel_dp) ? 675000 : 810000;
|
||||
return 810000;
|
||||
|
||||
return 2000000;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ struct intel_tc_port {
|
||||
struct delayed_work link_reset_work;
|
||||
int link_refcount;
|
||||
bool legacy_port:1;
|
||||
char port_name[8];
|
||||
const char *port_name;
|
||||
enum tc_port_mode mode;
|
||||
enum tc_port_mode init_mode;
|
||||
enum phy_fia phy_fia;
|
||||
@ -1875,8 +1875,12 @@ int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy)
|
||||
else
|
||||
tc->phy_ops = &icl_tc_phy_ops;
|
||||
|
||||
snprintf(tc->port_name, sizeof(tc->port_name),
|
||||
"%c/TC#%d", port_name(port), tc_port + 1);
|
||||
tc->port_name = kasprintf(GFP_KERNEL, "%c/TC#%d", port_name(port),
|
||||
tc_port + 1);
|
||||
if (!tc->port_name) {
|
||||
kfree(tc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_init(&tc->lock);
|
||||
/* TODO: Combine the two works */
|
||||
@ -1897,6 +1901,7 @@ void intel_tc_port_cleanup(struct intel_digital_port *dig_port)
|
||||
{
|
||||
intel_tc_port_suspend(dig_port);
|
||||
|
||||
kfree(dig_port->tc->port_name);
|
||||
kfree(dig_port->tc);
|
||||
dig_port->tc = NULL;
|
||||
}
|
||||
|
@ -844,6 +844,7 @@ static int set_proto_ctx_sseu(struct drm_i915_file_private *fpriv,
|
||||
if (idx >= pc->num_user_engines)
|
||||
return -EINVAL;
|
||||
|
||||
idx = array_index_nospec(idx, pc->num_user_engines);
|
||||
pe = &pc->user_engines[idx];
|
||||
|
||||
/* Only render engine supports RPCS configuration. */
|
||||
|
@ -195,6 +195,21 @@ void gen6_ggtt_invalidate(struct i915_ggtt *ggtt)
|
||||
spin_unlock_irq(&uncore->lock);
|
||||
}
|
||||
|
||||
static bool needs_wc_ggtt_mapping(struct drm_i915_private *i915)
|
||||
{
|
||||
/*
|
||||
* On BXT+/ICL+ writes larger than 64 bit to the GTT pagetable range
|
||||
* will be dropped. For WC mappings in general we have 64 byte burst
|
||||
* writes when the WC buffer is flushed, so we can't use it, but have to
|
||||
* resort to an uncached mapping. The WC issue is easily caught by the
|
||||
* readback check when writing GTT PTE entries.
|
||||
*/
|
||||
if (!IS_GEN9_LP(i915) && GRAPHICS_VER(i915) < 11)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gen8_ggtt_invalidate(struct i915_ggtt *ggtt)
|
||||
{
|
||||
struct intel_uncore *uncore = ggtt->vm.gt->uncore;
|
||||
@ -202,8 +217,12 @@ static void gen8_ggtt_invalidate(struct i915_ggtt *ggtt)
|
||||
/*
|
||||
* Note that as an uncached mmio write, this will flush the
|
||||
* WCB of the writes into the GGTT before it triggers the invalidate.
|
||||
*
|
||||
* Only perform this when GGTT is mapped as WC, see ggtt_probe_common().
|
||||
*/
|
||||
intel_uncore_write_fw(uncore, GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
|
||||
if (needs_wc_ggtt_mapping(ggtt->vm.i915))
|
||||
intel_uncore_write_fw(uncore, GFX_FLSH_CNTL_GEN6,
|
||||
GFX_FLSH_CNTL_EN);
|
||||
}
|
||||
|
||||
static void guc_ggtt_ct_invalidate(struct intel_gt *gt)
|
||||
@ -1140,17 +1159,11 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
|
||||
GEM_WARN_ON(pci_resource_len(pdev, GEN4_GTTMMADR_BAR) != gen6_gttmmadr_size(i915));
|
||||
phys_addr = pci_resource_start(pdev, GEN4_GTTMMADR_BAR) + gen6_gttadr_offset(i915);
|
||||
|
||||
/*
|
||||
* On BXT+/ICL+ writes larger than 64 bit to the GTT pagetable range
|
||||
* will be dropped. For WC mappings in general we have 64 byte burst
|
||||
* writes when the WC buffer is flushed, so we can't use it, but have to
|
||||
* resort to an uncached mapping. The WC issue is easily caught by the
|
||||
* readback check when writing GTT PTE entries.
|
||||
*/
|
||||
if (IS_GEN9_LP(i915) || GRAPHICS_VER(i915) >= 11)
|
||||
ggtt->gsm = ioremap(phys_addr, size);
|
||||
else
|
||||
if (needs_wc_ggtt_mapping(i915))
|
||||
ggtt->gsm = ioremap_wc(phys_addr, size);
|
||||
else
|
||||
ggtt->gsm = ioremap(phys_addr, size);
|
||||
|
||||
if (!ggtt->gsm) {
|
||||
drm_err(&i915->drm, "Failed to map the ggtt page table\n");
|
||||
return -ENOMEM;
|
||||
|
@ -581,19 +581,23 @@ static void __intel_rc6_disable(struct intel_rc6 *rc6)
|
||||
|
||||
static void rc6_res_reg_init(struct intel_rc6 *rc6)
|
||||
{
|
||||
memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));
|
||||
i915_reg_t res_reg[INTEL_RC6_RES_MAX] = {
|
||||
[0 ... INTEL_RC6_RES_MAX - 1] = INVALID_MMIO_REG,
|
||||
};
|
||||
|
||||
switch (rc6_to_gt(rc6)->type) {
|
||||
case GT_MEDIA:
|
||||
rc6->res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6;
|
||||
res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6;
|
||||
break;
|
||||
default:
|
||||
rc6->res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED;
|
||||
rc6->res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6;
|
||||
rc6->res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p;
|
||||
rc6->res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp;
|
||||
res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED;
|
||||
res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6;
|
||||
res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p;
|
||||
res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(rc6->res_reg, res_reg, sizeof(res_reg));
|
||||
}
|
||||
|
||||
void intel_rc6_init(struct intel_rc6 *rc6)
|
||||
|
@ -38,10 +38,13 @@ static int i915_param_int_open(struct inode *inode, struct file *file)
|
||||
|
||||
static int notify_guc(struct drm_i915_private *i915)
|
||||
{
|
||||
int ret = 0;
|
||||
struct intel_gt *gt;
|
||||
int i, ret = 0;
|
||||
|
||||
if (intel_uc_uses_guc_submission(&to_gt(i915)->uc))
|
||||
ret = intel_guc_global_policies_update(&to_gt(i915)->uc.guc);
|
||||
for_each_gt(gt, i915, i) {
|
||||
if (intel_uc_uses_guc_submission(>->uc))
|
||||
ret = intel_guc_global_policies_update(>->uc.guc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -4227,11 +4227,8 @@ int i915_perf_open_ioctl(struct drm_device *dev, void *data,
|
||||
u32 known_open_flags;
|
||||
int ret;
|
||||
|
||||
if (!perf->i915) {
|
||||
drm_dbg(&perf->i915->drm,
|
||||
"i915 perf interface not available for this system\n");
|
||||
if (!perf->i915)
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
known_open_flags = I915_PERF_FLAG_FD_CLOEXEC |
|
||||
I915_PERF_FLAG_FD_NONBLOCK |
|
||||
@ -4607,11 +4604,8 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
|
||||
struct i915_oa_reg *regs;
|
||||
int err, id;
|
||||
|
||||
if (!perf->i915) {
|
||||
drm_dbg(&perf->i915->drm,
|
||||
"i915 perf interface not available for this system\n");
|
||||
if (!perf->i915)
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (!perf->metrics_kobj) {
|
||||
drm_dbg(&perf->i915->drm,
|
||||
@ -4773,11 +4767,8 @@ int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data,
|
||||
struct i915_oa_config *oa_config;
|
||||
int ret;
|
||||
|
||||
if (!perf->i915) {
|
||||
drm_dbg(&perf->i915->drm,
|
||||
"i915 perf interface not available for this system\n");
|
||||
if (!perf->i915)
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (i915_perf_stream_paranoid && !perfmon_capable()) {
|
||||
drm_dbg(&perf->i915->drm,
|
||||
|
Loading…
Reference in New Issue
Block a user