AMD-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
  • * [PATCH AUTOSEL 5.0 078/262] drm/amd/display: Fix reference counting for struct dc_sink.
           [not found] <20190327180158.10245-1-sashal@kernel.org>
           [not found] ` <20190327180158.10245-1-sashal-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
    @ 2019-03-27 17:58 ` Sasha Levin
      2019-03-27 17:59 ` [PATCH AUTOSEL 5.0 114/262] drm/amd/display: Clear stream->mode_changed after commit Sasha Levin
      2019-03-27 18:01 ` [PATCH AUTOSEL 5.0 207/262] drm/amd/display: Enable vblank interrupt during CRC capture Sasha Levin
      3 siblings, 0 replies; 7+ messages in thread
    From: Sasha Levin @ 2019-03-27 17:58 UTC (permalink / raw)
      To: linux-kernel, stable
      Cc: Alex Deucher, Sasha Levin, dri-devel, amd-gfx,
    	Mathias Fröhlich
    
    From: Mathias Fröhlich <Mathias.Froehlich@web.de>
    
    [ Upstream commit dcd5fb82ffb484124203aa339733663ac0b059f3 ]
    
    Reference counting in amdgpu_dm_connector for amdgpu_dm_connector::dc_sink
    and amdgpu_dm_connector::dc_em_sink as well as in dc_link::local_sink seems
    to be out of shape. Thus make reference counting consistent for these
    members and just plain increment the reference count when the variable
    gets assigned and decrement when the pointer is set to zero or replaced.
    Also simplify reference counting in selected function sopes to be sure the
    reference is released in any case. In some cases add NULL pointer check
    before dereferencing.
    At a hand full of places a comment is placed to stat that the reference
    increment happened already somewhere else.
    
    This actually fixes the following kernel bug on my system when enabling
    display core in amdgpu. There are some more similar bug reports around,
    so it probably helps at more places.
    
       kernel BUG at mm/slub.c:294!
       invalid opcode: 0000 [#1] SMP PTI
       CPU: 9 PID: 1180 Comm: Xorg Not tainted 5.0.0-rc1+ #2
       Hardware name: Supermicro X10DAi/X10DAI, BIOS 3.0a 02/05/2018
       RIP: 0010:__slab_free+0x1e2/0x3d0
       Code: 8b 54 24 30 48 89 4c 24 28 e8 da fb ff ff 4c 8b 54 24 28 85 c0 0f 85 67 fe ff ff 48 8d 65 d8 5b 41 5c 41 5d 41 5e 41 5f 5d c3 <0f> 0b 49 3b 5c 24 28 75 ab 48 8b 44 24 30 49 89 4c 24 28 49 89 44
       RSP: 0018:ffffb0978589fa90 EFLAGS: 00010246
       RAX: ffff92f12806c400 RBX: 0000000080200019 RCX: ffff92f12806c400
       RDX: ffff92f12806c400 RSI: ffffdd6421a01a00 RDI: ffff92ed2f406e80
       RBP: ffffb0978589fb40 R08: 0000000000000001 R09: ffffffffc0ee4748
       R10: ffff92f12806c400 R11: 0000000000000001 R12: ffffdd6421a01a00
       R13: ffff92f12806c400 R14: ffff92ed2f406e80 R15: ffffdd6421a01a20
       FS:  00007f4170be0ac0(0000) GS:ffff92ed2fb40000(0000) knlGS:0000000000000000
       CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
       CR2: 0000562818aaa000 CR3: 000000045745a002 CR4: 00000000003606e0
       DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
       DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
       Call Trace:
        ? drm_dbg+0x87/0x90 [drm]
        dc_stream_release+0x28/0x50 [amdgpu]
        amdgpu_dm_connector_mode_valid+0xb4/0x1f0 [amdgpu]
        drm_helper_probe_single_connector_modes+0x492/0x6b0 [drm_kms_helper]
        drm_mode_getconnector+0x457/0x490 [drm]
        ? drm_connector_property_set_ioctl+0x60/0x60 [drm]
        drm_ioctl_kernel+0xa9/0xf0 [drm]
        drm_ioctl+0x201/0x3a0 [drm]
        ? drm_connector_property_set_ioctl+0x60/0x60 [drm]
        amdgpu_drm_ioctl+0x49/0x80 [amdgpu]
        do_vfs_ioctl+0xa4/0x630
        ? __sys_recvmsg+0x83/0xa0
        ksys_ioctl+0x60/0x90
        __x64_sys_ioctl+0x16/0x20
        do_syscall_64+0x5b/0x160
        entry_SYSCALL_64_after_hwframe+0x44/0xa9
       RIP: 0033:0x7f417110809b
       Code: 0f 1e fa 48 8b 05 ed bd 0c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d bd bd 0c 00 f7 d8 64 89 01 48
       RSP: 002b:00007ffdd8d1c268 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
       RAX: ffffffffffffffda RBX: 0000562818a8ebc0 RCX: 00007f417110809b
       RDX: 00007ffdd8d1c2a0 RSI: 00000000c05064a7 RDI: 0000000000000012
       RBP: 00007ffdd8d1c2a0 R08: 0000562819012280 R09: 0000000000000007
       R10: 0000000000000000 R11: 0000000000000246 R12: 00000000c05064a7
       R13: 0000000000000012 R14: 0000000000000012 R15: 00007ffdd8d1c2a0
       Modules linked in: nfsv4 dns_resolver nfs lockd grace fscache fuse vfat fat amdgpu intel_rapl sb_edac x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel kvm irqbypass crct10dif_pclmul chash gpu_sched crc32_pclmul snd_hda_codec_realtek ghash_clmulni_intel amd_iommu_v2 iTCO_wdt iTCO_vendor_support ttm snd_hda_codec_generic snd_hda_codec_hdmi ledtrig_audio snd_hda_intel drm_kms_helper snd_hda_codec intel_cstate snd_hda_core drm snd_hwdep snd_seq snd_seq_device intel_uncore snd_pcm intel_rapl_perf snd_timer snd soundcore ioatdma pcspkr intel_wmi_thunderbolt mxm_wmi i2c_i801 lpc_ich pcc_cpufreq auth_rpcgss sunrpc igb crc32c_intel i2c_algo_bit dca wmi hid_cherry analog gameport joydev
    
    This patch is based on agd5f/drm-next-5.1-wip. This patch does not require
    all of that, but agd5f/drm-next-5.1-wip contains at least one more dc_sink
    counting fix that I could spot.
    
    Signed-off-by: Mathias Fröhlich <Mathias.Froehlich@web.de>
    Reviewed-by: Leo Li <sunpeng.li@amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
     .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 43 +++++++++++++++----
     .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  1 +
     drivers/gpu/drm/amd/display/dc/core/dc_link.c |  1 +
     3 files changed, 37 insertions(+), 8 deletions(-)
    
    diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
    index 636d14a60952..6d77fd966dbd 100644
    --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
    +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
    @@ -886,6 +886,7 @@ static void emulated_link_detect(struct dc_link *link)
     		return;
     	}
     
    +	/* dc_sink_create returns a new reference */
     	link->local_sink = sink;
     
     	edid_status = dm_helpers_read_local_edid(
    @@ -952,6 +953,8 @@ static int dm_resume(void *handle)
     		if (aconnector->fake_enable && aconnector->dc_link->local_sink)
     			aconnector->fake_enable = false;
     
    +		if (aconnector->dc_sink)
    +			dc_sink_release(aconnector->dc_sink);
     		aconnector->dc_sink = NULL;
     		amdgpu_dm_update_connector_after_detect(aconnector);
     		mutex_unlock(&aconnector->hpd_lock);
    @@ -1061,6 +1064,8 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
     
     
     	sink = aconnector->dc_link->local_sink;
    +	if (sink)
    +		dc_sink_retain(sink);
     
     	/*
     	 * Edid mgmt connector gets first update only in mode_valid hook and then
    @@ -1085,21 +1090,24 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
     				 * to it anymore after disconnect, so on next crtc to connector
     				 * reshuffle by UMD we will get into unwanted dc_sink release
     				 */
    -				if (aconnector->dc_sink != aconnector->dc_em_sink)
    -					dc_sink_release(aconnector->dc_sink);
    +				dc_sink_release(aconnector->dc_sink);
     			}
     			aconnector->dc_sink = sink;
    +			dc_sink_retain(aconnector->dc_sink);
     			amdgpu_dm_update_freesync_caps(connector,
     					aconnector->edid);
     		} else {
     			amdgpu_dm_update_freesync_caps(connector, NULL);
    -			if (!aconnector->dc_sink)
    +			if (!aconnector->dc_sink) {
     				aconnector->dc_sink = aconnector->dc_em_sink;
    -			else if (aconnector->dc_sink != aconnector->dc_em_sink)
     				dc_sink_retain(aconnector->dc_sink);
    +			}
     		}
     
     		mutex_unlock(&dev->mode_config.mutex);
    +
    +		if (sink)
    +			dc_sink_release(sink);
     		return;
     	}
     
    @@ -1107,8 +1115,10 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
     	 * TODO: temporary guard to look for proper fix
     	 * if this sink is MST sink, we should not do anything
     	 */
    -	if (sink && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
    +	if (sink && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
    +		dc_sink_release(sink);
     		return;
    +	}
     
     	if (aconnector->dc_sink == sink) {
     		/*
    @@ -1117,6 +1127,8 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
     		 */
     		DRM_DEBUG_DRIVER("DCHPD: connector_id=%d: dc_sink didn't change.\n",
     				aconnector->connector_id);
    +		if (sink)
    +			dc_sink_release(sink);
     		return;
     	}
     
    @@ -1138,6 +1150,7 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
     			amdgpu_dm_update_freesync_caps(connector, NULL);
     
     		aconnector->dc_sink = sink;
    +		dc_sink_retain(aconnector->dc_sink);
     		if (sink->dc_edid.length == 0) {
     			aconnector->edid = NULL;
     			drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux);
    @@ -1158,11 +1171,15 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
     		amdgpu_dm_update_freesync_caps(connector, NULL);
     		drm_connector_update_edid_property(connector, NULL);
     		aconnector->num_modes = 0;
    +		dc_sink_release(aconnector->dc_sink);
     		aconnector->dc_sink = NULL;
     		aconnector->edid = NULL;
     	}
     
     	mutex_unlock(&dev->mode_config.mutex);
    +
    +	if (sink)
    +		dc_sink_release(sink);
     }
     
     static void handle_hpd_irq(void *param)
    @@ -2908,6 +2925,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
     		}
     	} else {
     		sink = aconnector->dc_sink;
    +		dc_sink_retain(sink);
     	}
     
     	stream = dc_create_stream_for_sink(sink);
    @@ -2974,8 +2992,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
     		stream->ignore_msa_timing_param = true;
     
     finish:
    -	if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL && aconnector->base.force != DRM_FORCE_ON)
    -		dc_sink_release(sink);
    +	dc_sink_release(sink);
     
     	return stream;
     }
    @@ -3233,6 +3250,14 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
     		dm->backlight_dev = NULL;
     	}
     #endif
    +
    +	if (aconnector->dc_em_sink)
    +		dc_sink_release(aconnector->dc_em_sink);
    +	aconnector->dc_em_sink = NULL;
    +	if (aconnector->dc_sink)
    +		dc_sink_release(aconnector->dc_sink);
    +	aconnector->dc_sink = NULL;
    +
     	drm_dp_cec_unregister_connector(&aconnector->dm_dp_aux.aux);
     	drm_connector_unregister(connector);
     	drm_connector_cleanup(connector);
    @@ -3330,10 +3355,12 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
     		(edid->extensions + 1) * EDID_LENGTH,
     		&init_params);
     
    -	if (aconnector->base.force == DRM_FORCE_ON)
    +	if (aconnector->base.force == DRM_FORCE_ON) {
     		aconnector->dc_sink = aconnector->dc_link->local_sink ?
     		aconnector->dc_link->local_sink :
     		aconnector->dc_em_sink;
    +		dc_sink_retain(aconnector->dc_sink);
    +	}
     }
     
     static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector)
    diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
    index 1b0d209d8367..3b95a637b508 100644
    --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
    +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
    @@ -239,6 +239,7 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
     			&init_params);
     
     		dc_sink->priv = aconnector;
    +		/* dc_link_add_remote_sink returns a new reference */
     		aconnector->dc_sink = dc_sink;
     
     		if (aconnector->dc_sink)
    diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
    index b0265dbebd4c..583eb367850f 100644
    --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
    +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
    @@ -792,6 +792,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
     		sink->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock;
     		sink->converter_disable_audio = converter_disable_audio;
     
    +		/* dc_sink_create returns a new reference */
     		link->local_sink = sink;
     
     		edid_status = dm_helpers_read_local_edid(
    -- 
    2.19.1
    
    _______________________________________________
    dri-devel mailing list
    dri-devel@lists.freedesktop.org
    https://lists.freedesktop.org/mailman/listinfo/dri-devel
    
    ^ permalink raw reply related	[flat|nested] 7+ messages in thread
  • * [PATCH AUTOSEL 5.0 114/262] drm/amd/display: Clear stream->mode_changed after commit
           [not found] <20190327180158.10245-1-sashal@kernel.org>
           [not found] ` <20190327180158.10245-1-sashal-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
      2019-03-27 17:58 ` [PATCH AUTOSEL 5.0 078/262] drm/amd/display: Fix reference counting for struct dc_sink Sasha Levin
    @ 2019-03-27 17:59 ` Sasha Levin
      2019-03-27 18:01 ` [PATCH AUTOSEL 5.0 207/262] drm/amd/display: Enable vblank interrupt during CRC capture Sasha Levin
      3 siblings, 0 replies; 7+ messages in thread
    From: Sasha Levin @ 2019-03-27 17:59 UTC (permalink / raw)
      To: linux-kernel, stable
      Cc: Alex Deucher, Sasha Levin, dri-devel, Nicholas Kazlauskas,
    	amd-gfx
    
    From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
    
    [ Upstream commit d8d2f174bcc2c26c3485c70e0c6fe22b27bce739 ]
    
    [Why]
    The stream->mode_changed flag can persist in the following sequence
    of atomic commits:
    
    Commit 1:
    Enable CRTC0 (mode_changed = true), Enable CRTC1 (mode_changed = true)
    
    Commit 2:
    Disable CRTC1 (mode_changed = false)
    
    In this sequence we want to keep the exiting CRTC0 but it's not in the
    atomic state for the commit since it hasn't been modified. In this case
    the stream->mode_changed flag persists as true and we don't re-program
    the planes for the existing stream.
    
    [How]
    The flag needs to be cleared and it makes the most sense to do it within
    DC after the state has been committed. Nothing following dc_commit_state
    should think that the stream's mode has changed.
    
    Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
    Reviewed-by: Leo Li <sunpeng.li@amd.com>
    Acked-by: Tony Cheng <Tony.Cheng@amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
     drivers/gpu/drm/amd/display/dc/core/dc.c | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
    index 5fd52094d459..1f92e7e8e3d3 100644
    --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
    +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
    @@ -1078,6 +1078,9 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
     	/* pplib is notified if disp_num changed */
     	dc->hwss.optimize_bandwidth(dc, context);
     
    +	for (i = 0; i < context->stream_count; i++)
    +		context->streams[i]->mode_changed = false;
    +
     	dc_release_state(dc->current_state);
     
     	dc->current_state = context;
    -- 
    2.19.1
    
    _______________________________________________
    dri-devel mailing list
    dri-devel@lists.freedesktop.org
    https://lists.freedesktop.org/mailman/listinfo/dri-devel
    
    ^ permalink raw reply related	[flat|nested] 7+ messages in thread
  • * [PATCH AUTOSEL 5.0 207/262] drm/amd/display: Enable vblank interrupt during CRC capture
           [not found] <20190327180158.10245-1-sashal@kernel.org>
                       ` (2 preceding siblings ...)
      2019-03-27 17:59 ` [PATCH AUTOSEL 5.0 114/262] drm/amd/display: Clear stream->mode_changed after commit Sasha Levin
    @ 2019-03-27 18:01 ` Sasha Levin
      3 siblings, 0 replies; 7+ messages in thread
    From: Sasha Levin @ 2019-03-27 18:01 UTC (permalink / raw)
      To: linux-kernel, stable
      Cc: Alex Deucher, Sasha Levin, dri-devel, Nicholas Kazlauskas,
    	amd-gfx
    
    From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
    
    [ Upstream commit 428da2bdb05d76c48d0bd8fbfa2e4c102685be08 ]
    
    [Why]
    In order to read CRC events when CRC capture is enabled the vblank
    interrput handler needs to be running for the CRTC. The handler is
    enabled while there is an active vblank reference.
    
    When running IGT tests there will often be no active vblank reference
    but the test expects to read a CRC value. This is valid usage (and
    works on i915 since they have a CRC interrupt handler) so the reference
    to the vblank should be grabbed while capture is active.
    
    This issue was found running:
    
    igt@kms_plane_multiple@atomic-pipe-b-tiling-none
    
    The pipe-b is the only one in the initial commit and was not previously
    active so no vblank reference is grabbed. The vblank interrupt is
    not enabled and the test times out.
    
    [How]
    Keep a reference to the vblank as long as CRC capture is enabled.
    If userspace never explicitly disables it then the reference is
    also dropped when removing the CRTC from the context (stream = NULL).
    
    Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
    Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
    Reviewed-by: Sun peng Li <Sunpeng.Li@amd.com>
    Acked-by: Leo Li <sunpeng.li@amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
     .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 ++++++-
     .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 42 +++++++++----------
     2 files changed, 34 insertions(+), 22 deletions(-)
    
    diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
    index 0040605cace8..83c8a0407537 100644
    --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
    +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
    @@ -4997,10 +4997,22 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev,
     	 */
     	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
     		struct dm_crtc_state *dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
    +		struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
     		struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
     
    -		if (drm_atomic_crtc_needs_modeset(new_crtc_state) && dm_old_crtc_state->stream)
    +		if (drm_atomic_crtc_needs_modeset(new_crtc_state)
    +		    && dm_old_crtc_state->stream) {
    +			/*
    +			 * CRC capture was enabled but not disabled.
    +			 * Release the vblank reference.
    +			 */
    +			if (dm_new_crtc_state->crc_enabled) {
    +				drm_crtc_vblank_put(crtc);
    +				dm_new_crtc_state->crc_enabled = false;
    +			}
    +
     			manage_dm_interrupts(adev, acrtc, false);
    +		}
     	}
     	/*
     	 * Add check here for SoC's that support hardware cursor plane, to
    diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
    index f088ac585978..26b651148c67 100644
    --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
    +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
    @@ -66,6 +66,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
     {
     	struct dm_crtc_state *crtc_state = to_dm_crtc_state(crtc->state);
     	struct dc_stream_state *stream_state = crtc_state->stream;
    +	bool enable;
     
     	enum amdgpu_dm_pipe_crc_source source = dm_parse_crc_source(src_name);
     
    @@ -80,28 +81,27 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
     		return -EINVAL;
     	}
     
    +	enable = (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO);
    +
    +	if (!dc_stream_configure_crc(stream_state->ctx->dc, stream_state,
    +				     enable, enable))
    +		return -EINVAL;
    +
     	/* When enabling CRC, we should also disable dithering. */
    -	if (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO) {
    -		if (dc_stream_configure_crc(stream_state->ctx->dc,
    -					    stream_state,
    -					    true, true)) {
    -			crtc_state->crc_enabled = true;
    -			dc_stream_set_dither_option(stream_state,
    -						    DITHER_OPTION_TRUN8);
    -		}
    -		else
    -			return -EINVAL;
    -	} else {
    -		if (dc_stream_configure_crc(stream_state->ctx->dc,
    -					    stream_state,
    -					    false, false)) {
    -			crtc_state->crc_enabled = false;
    -			dc_stream_set_dither_option(stream_state,
    -						    DITHER_OPTION_DEFAULT);
    -		}
    -		else
    -			return -EINVAL;
    -	}
    +	dc_stream_set_dither_option(stream_state,
    +				    enable ? DITHER_OPTION_TRUN8
    +					   : DITHER_OPTION_DEFAULT);
    +
    +	/*
    +	 * Reading the CRC requires the vblank interrupt handler to be
    +	 * enabled. Keep a reference until CRC capture stops.
    +	 */
    +	if (!crtc_state->crc_enabled && enable)
    +		drm_crtc_vblank_get(crtc);
    +	else if (crtc_state->crc_enabled && !enable)
    +		drm_crtc_vblank_put(crtc);
    +
    +	crtc_state->crc_enabled = enable;
     
     	/* Reset crc_skipped on dm state */
     	crtc_state->crc_skip_count = 0;
    -- 
    2.19.1
    
    _______________________________________________
    dri-devel mailing list
    dri-devel@lists.freedesktop.org
    https://lists.freedesktop.org/mailman/listinfo/dri-devel
    
    ^ permalink raw reply related	[flat|nested] 7+ messages in thread

  • end of thread, other threads:[~2019-03-28 10:04 UTC | newest]
    
    Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
    -- links below jump to the message on this page --
         [not found] <20190327180158.10245-1-sashal@kernel.org>
         [not found] ` <20190327180158.10245-1-sashal-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
    2019-03-27 17:58   ` [PATCH AUTOSEL 5.0 070/262] drm/amd/display: Pass app_tf by value rather than by reference Sasha Levin
    2019-03-28 10:04     ` Pavel Machek
    2019-03-27 18:00   ` [PATCH AUTOSEL 5.0 171/262] drm/amd/display: Don't re-program planes for DPMS changes Sasha Levin
    2019-03-27 18:00   ` [PATCH AUTOSEL 5.0 175/262] drm/amd/display: Disconnect mpcc when changing tg Sasha Levin
    2019-03-27 17:58 ` [PATCH AUTOSEL 5.0 078/262] drm/amd/display: Fix reference counting for struct dc_sink Sasha Levin
    2019-03-27 17:59 ` [PATCH AUTOSEL 5.0 114/262] drm/amd/display: Clear stream->mode_changed after commit Sasha Levin
    2019-03-27 18:01 ` [PATCH AUTOSEL 5.0 207/262] drm/amd/display: Enable vblank interrupt during CRC capture Sasha Levin
    

    This is a public inbox, see mirroring instructions
    for how to clone and mirror all data and code used for this inbox