diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index a6ade66349bd..25f78196b964 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -1254,18 +1254,15 @@ static int send_display_ready_uevent(struct intel_vgpu *vgpu, int ready) static int pvinfo_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes) { - u32 data; - int ret; - - write_vreg(vgpu, offset, p_data, bytes); - data = vgpu_vreg(vgpu, offset); + u32 data = *(u32 *)p_data; + bool invalid_write = false; switch (offset) { case _vgtif_reg(display_ready): send_display_ready_uevent(vgpu, data ? 1 : 0); break; case _vgtif_reg(g2v_notify): - ret = handle_g2v_notification(vgpu, data); + handle_g2v_notification(vgpu, data); break; /* add xhot and yhot to handled list to avoid error log */ case _vgtif_reg(cursor_x_hot): @@ -1282,13 +1279,19 @@ static int pvinfo_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, case _vgtif_reg(execlist_context_descriptor_hi): break; case _vgtif_reg(rsv5[0])..._vgtif_reg(rsv5[3]): + invalid_write = true; enter_failsafe_mode(vgpu, GVT_FAILSAFE_INSUFFICIENT_RESOURCE); break; default: + invalid_write = true; gvt_vgpu_err("invalid pvinfo write offset %x bytes %x data %x\n", offset, bytes, data); break; } + + if (!invalid_write) + write_vreg(vgpu, offset, p_data, bytes); + return 0; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b69440cf41ea..75105a2c59ea 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12005,9 +12005,6 @@ intel_compare_link_m_n(const struct intel_link_m_n *m_n, m2_n2->gmch_m, m2_n2->gmch_n, !adjust) && intel_compare_m_n(m_n->link_m, m_n->link_n, m2_n2->link_m, m2_n2->link_n, !adjust)) { - if (adjust) - *m2_n2 = *m_n; - return true; } @@ -13149,6 +13146,33 @@ static int calc_watermark_data(struct intel_atomic_state *state) return 0; } +static void intel_crtc_check_fastset(struct intel_crtc_state *old_crtc_state, + struct intel_crtc_state *new_crtc_state) +{ + struct drm_i915_private *dev_priv = + to_i915(new_crtc_state->base.crtc->dev); + + if (!intel_pipe_config_compare(dev_priv, old_crtc_state, + new_crtc_state, true)) + return; + + new_crtc_state->base.mode_changed = false; + new_crtc_state->update_pipe = true; + + /* + * If we're not doing the full modeset we want to + * keep the current M/N values as they may be + * sufficiently different to the computed values + * to cause problems. + * + * FIXME: should really copy more fuzzy state here + */ + new_crtc_state->fdi_m_n = old_crtc_state->fdi_m_n; + new_crtc_state->dp_m_n = old_crtc_state->dp_m_n; + new_crtc_state->dp_m2_n2 = old_crtc_state->dp_m2_n2; + new_crtc_state->has_drrs = old_crtc_state->has_drrs; +} + /** * intel_atomic_check - validate state object * @dev: drm device @@ -13197,12 +13221,8 @@ static int intel_atomic_check(struct drm_device *dev, return ret; } - if (intel_pipe_config_compare(dev_priv, - to_intel_crtc_state(old_crtc_state), - pipe_config, true)) { - crtc_state->mode_changed = false; - pipe_config->update_pipe = true; - } + intel_crtc_check_fastset(to_intel_crtc_state(old_crtc_state), + pipe_config); if (needs_modeset(crtc_state)) any_ms = true;