Skip to content

Commit

Permalink
Merge tag 'drm-intel-next-fixes-2019-11-14' of git://anongit.freedesk…
Browse files Browse the repository at this point in the history
…top.org/drm/drm-intel into drm-next

- PMU "Frequency" is reported as accumulated cycles
- Avoid OOPS in dumb_create IOCTL when no CRTCs
- Mitigation for userptr put_pages deadlock with trylock_page
- Fix to avoid freeing heartbeat request too early
- Fix LRC coherency issue
- Fix Bugzilla #112212: Avoid screen corruption on MST
- Error path fix to unlock context on failed context VM SETPARAM
- Always consider holding preemption a privileged op in perf/OA
- Preload LUTs if the hw isn't currently using them to avoid color flash on VLV/CHV
- Protect context while grabbing its name for the request
- Don't resize aliasing ppGTT size
- Smaller fixes picked by tooling

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191114085213.GA6440@jlahtine-desk.ger.corp.intel.com
  • Loading branch information
Dave Airlie committed Nov 15, 2019
2 parents dfce902 + 789c4ae commit 2d0720f
Show file tree
Hide file tree
Showing 15 changed files with 181 additions and 79 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/display/intel_atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
crtc_state->update_wm_pre = false;
crtc_state->update_wm_post = false;
crtc_state->fifo_changed = false;
crtc_state->preload_luts = false;
crtc_state->wm.need_postvbl_update = false;
crtc_state->fb_bits = 0;
crtc_state->update_planes = 0;
Expand Down
61 changes: 61 additions & 0 deletions drivers/gpu/drm/i915/display/intel_color.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,55 @@ void intel_color_commit(const struct intel_crtc_state *crtc_state)
dev_priv->display.color_commit(crtc_state);
}

static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
struct intel_atomic_state *state =
to_intel_atomic_state(new_crtc_state->base.state);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);

return !old_crtc_state->base.gamma_lut &&
!old_crtc_state->base.degamma_lut;
}

static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
struct intel_atomic_state *state =
to_intel_atomic_state(new_crtc_state->base.state);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);

/*
* CGM_PIPE_MODE is itself single buffered. We'd have to
* somehow split it out from chv_load_luts() if we wanted
* the ability to preload the CGM LUTs/CSC without tearing.
*/
if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
return false;

return !old_crtc_state->base.gamma_lut;
}

static bool glk_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
struct intel_atomic_state *state =
to_intel_atomic_state(new_crtc_state->base.state);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);

/*
* The hardware degamma is active whenever the pipe
* CSC is active. Thus even if the old state has no
* software degamma we need to avoid clobbering the
* linear hardware degamma mid scanout.
*/
return !old_crtc_state->csc_enable &&
!old_crtc_state->base.gamma_lut;
}

int intel_color_check(struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
Expand Down Expand Up @@ -1165,6 +1214,8 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state)
if (ret)
return ret;

crtc_state->preload_luts = intel_can_preload_luts(crtc_state);

return 0;
}

Expand Down Expand Up @@ -1217,6 +1268,8 @@ static int chv_color_check(struct intel_crtc_state *crtc_state)
if (ret)
return ret;

crtc_state->preload_luts = chv_can_preload_luts(crtc_state);

return 0;
}

Expand Down Expand Up @@ -1271,6 +1324,8 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state)
if (ret)
return ret;

crtc_state->preload_luts = intel_can_preload_luts(crtc_state);

return 0;
}

Expand Down Expand Up @@ -1328,6 +1383,8 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state)
if (ret)
return ret;

crtc_state->preload_luts = intel_can_preload_luts(crtc_state);

return 0;
}

Expand Down Expand Up @@ -1366,6 +1423,8 @@ static int glk_color_check(struct intel_crtc_state *crtc_state)
if (ret)
return ret;

crtc_state->preload_luts = glk_can_preload_luts(crtc_state);

return 0;
}

Expand Down Expand Up @@ -1415,6 +1474,8 @@ static int icl_color_check(struct intel_crtc_state *crtc_state)

crtc_state->csc_mode = icl_csc_mode(crtc_state);

crtc_state->preload_luts = intel_can_preload_luts(crtc_state);

return 0;
}

Expand Down
10 changes: 6 additions & 4 deletions drivers/gpu/drm/i915/display/intel_ddi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1794,10 +1794,8 @@ void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state,
* of Color Encoding Format and Content Color Gamut] while sending
* YCBCR 420, HDR BT.2020 signals we should program MSA MISC1 fields
* which indicate VSC SDP for the Pixel Encoding/Colorimetry Format.
*
* FIXME MST doesn't pass in the conn_state
*/
if (conn_state && intel_dp_needs_vsc_sdp(crtc_state, conn_state))
if (intel_dp_needs_vsc_sdp(crtc_state, conn_state))
temp |= DP_MSA_MISC_COLOR_VSC_SDP;

I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Expand Down Expand Up @@ -3605,7 +3603,11 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
else
hsw_ddi_pre_enable_dp(encoder, crtc_state, conn_state);

intel_ddi_set_dp_msa(crtc_state, conn_state);
/* MST will call a setting of MSA after an allocating of Virtual Channel
* from MST encoder pre_enable callback.
*/
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
intel_ddi_set_dp_msa(crtc_state, conn_state);
}

static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
Expand Down
10 changes: 10 additions & 0 deletions drivers/gpu/drm/i915/display/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "intel_cdclk.h"
#include "intel_color.h"
#include "intel_display_types.h"
#include "intel_dp_link_training.h"
#include "intel_fbc.h"
#include "intel_fbdev.h"
#include "intel_fifo_underrun.h"
Expand Down Expand Up @@ -2528,6 +2529,9 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
* the highest stride limits of them all.
*/
crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_A);
if (!crtc)
return 0;

plane = to_intel_plane(crtc->base.primary);

return plane->max_stride(plane, pixel_format, modifier,
Expand Down Expand Up @@ -14201,6 +14205,11 @@ static void intel_update_crtc(struct intel_crtc *crtc,
/* vblanks work again, re-enable pipe CRC. */
intel_crtc_enable_pipe_crc(crtc);
} else {
if (new_crtc_state->preload_luts &&
(new_crtc_state->base.color_mgmt_changed ||
new_crtc_state->update_pipe))
intel_color_load_luts(new_crtc_state);

intel_pre_plane_update(old_crtc_state, new_crtc_state);

if (new_crtc_state->update_pipe)
Expand Down Expand Up @@ -14713,6 +14722,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
if (new_crtc_state->base.active &&
!needs_modeset(new_crtc_state) &&
!new_crtc_state->preload_luts &&
(new_crtc_state->base.color_mgmt_changed ||
new_crtc_state->update_pipe))
intel_color_load_luts(new_crtc_state);
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/i915/display/intel_display.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

#include <drm/drm_util.h>
#include <drm/i915_drm.h>
#include "intel_dp_link_training.h"

enum link_m_n_set;
struct dpll;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/display/intel_display_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,7 @@ struct intel_crtc_state {
bool disable_cxsr;
bool update_wm_pre, update_wm_post; /* watermarks are updated */
bool fifo_changed; /* FIFO split is changed */
bool preload_luts;

/* Pipe source size (ie. panel fitter input size)
* All planes will be positioned inside this space,
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/display/intel_dp_mst.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);

intel_ddi_enable_pipe_clock(pipe_config);

intel_ddi_set_dp_msa(pipe_config, conn_state);
}

static void intel_mst_enable_dp(struct intel_encoder *encoder,
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/gem/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,7 @@ static int set_ppgtt(struct drm_i915_file_private *file_priv,

if (i915_gem_context_is_closed(ctx)) {
err = -ENOENT;
goto out;
goto unlock;
}

if (vm == rcu_access_pointer(ctx->vm))
Expand Down
22 changes: 21 additions & 1 deletion drivers/gpu/drm/i915/gem/i915_gem_userptr.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,8 +646,28 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj,
obj->mm.dirty = false;

for_each_sgt_page(page, sgt_iter, pages) {
if (obj->mm.dirty)
if (obj->mm.dirty && trylock_page(page)) {
/*
* As this may not be anonymous memory (e.g. shmem)
* but exist on a real mapping, we have to lock
* the page in order to dirty it -- holding
* the page reference is not sufficient to
* prevent the inode from being truncated.
* Play safe and take the lock.
*
* However...!
*
* The mmu-notifier can be invalidated for a
* migrate_page, that is alreadying holding the lock
* on the page. Such a try_to_unmap() will result
* in us calling put_pages() and so recursively try
* to lock the page. We avoid that deadlock with
* a trylock_page() and in exchange we risk missing
* some page dirtying.
*/
set_page_dirty(page);
unlock_page(page);
}

mark_page_accessed(page);
put_page(page);
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/gt/intel_engine_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1372,6 +1372,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
}

execlists_active_lock_bh(execlists);
rcu_read_lock();
for (port = execlists->active; (rq = *port); port++) {
char hdr[80];
int len;
Expand Down Expand Up @@ -1409,6 +1410,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine,
if (tl)
intel_timeline_put(tl);
}
rcu_read_unlock();
execlists_active_unlock_bh(execlists);
} else if (INTEL_GEN(dev_priv) > 6) {
drm_printf(m, "\tPP_DIR_BASE: 0x%08x\n",
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ void intel_engine_unpark_heartbeat(struct intel_engine_cs *engine)

void intel_engine_park_heartbeat(struct intel_engine_cs *engine)
{
cancel_delayed_work(&engine->heartbeat.work);
i915_request_put(fetch_and_zero(&engine->heartbeat.systole));
if (cancel_delayed_work(&engine->heartbeat.work))
i915_request_put(fetch_and_zero(&engine->heartbeat.systole));
}

void intel_engine_init_heartbeat(struct intel_engine_cs *engine)
Expand Down
Loading

0 comments on commit 2d0720f

Please sign in to comment.