diff options
author | Eryk Brol <eryk.brol@amd.com> | 2020-10-15 13:07:09 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2020-11-02 15:31:16 -0500 |
commit | 886876ecf7f46917af8065bb574a669f19302f96 (patch) | |
tree | 12fee29f6c54dccda7a19b738b8189d1e20ac7f5 /drivers | |
parent | 3a372bed1e337efa450d8288bc75cfc9237b7bad (diff) |
drm/amd/display: Update connector on DSC property change
[Why]
We want to trigger atomic check on connector when
DSC debugfs properties are changed. The previous
method was reverted because it accessed connector
properties unsafely and would also heavily
impact performance.
[How]
Add a flag for forcing DSC update in CRTC state
and add connector to the state if the flag is set.
Signed-off-by: Eryk Brol <eryk.brol@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 124 |
3 files changed, 130 insertions, 1 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 cfa7126e54f6..0448835e3e34 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -9120,6 +9120,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, enum dc_status status; int ret, i; bool lock_and_validation_needed = false; + struct dm_crtc_state *dm_old_crtc_state; trace_amdgpu_dm_atomic_check_begin(state); @@ -9162,9 +9163,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, } #endif for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); + if (!drm_atomic_crtc_needs_modeset(new_crtc_state) && !new_crtc_state->color_mgmt_changed && - old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled) + old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled && + dm_old_crtc_state->dsc_force_changed == false) continue; if (!new_crtc_state->enable) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 03e7e4f23178..7798eb018257 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -438,6 +438,7 @@ struct dm_crtc_state { bool freesync_timing_changed; bool freesync_vrr_info_changed; + bool dsc_force_changed; bool vrr_supported; struct mod_freesync_config freesync_config; struct dc_info_packet vrr_infopacket; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index cdc8dd220a77..d31380ea57dc 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -1253,6 +1253,10 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, size_t size, loff_t *pos) { struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; + struct drm_connector *connector = &aconnector->base; + struct drm_device *dev = connector->dev; + struct drm_crtc *crtc = NULL; + struct dm_crtc_state *dm_crtc_state = NULL; struct pipe_ctx *pipe_ctx; int i; char *wr_buf = NULL; @@ -1295,6 +1299,25 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, if (!pipe_ctx || !pipe_ctx->stream) goto done; + // Get CRTC state + mutex_lock(&dev->mode_config.mutex); + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + + if (connector->state == NULL) + goto unlock; + + crtc = connector->state->crtc; + if (crtc == NULL) + goto unlock; + + drm_modeset_lock(&crtc->mutex, NULL); + if (crtc->state == NULL) + goto unlock; + + dm_crtc_state = to_dm_crtc_state(crtc->state); + if (dm_crtc_state->stream == NULL) + goto unlock; + if (param[0] == 1) aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_ENABLE; else if (param[0] == 2) @@ -1302,6 +1325,14 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, else aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_DEFAULT; + dm_crtc_state->dsc_force_changed = true; + +unlock: + if (crtc) + drm_modeset_unlock(&crtc->mutex); + drm_modeset_unlock(&dev->mode_config.connection_mutex); + mutex_unlock(&dev->mode_config.mutex); + done: kfree(wr_buf); return size; @@ -1408,6 +1439,10 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf, { struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; struct pipe_ctx *pipe_ctx; + struct drm_connector *connector = &aconnector->base; + struct drm_device *dev = connector->dev; + struct drm_crtc *crtc = NULL; + struct dm_crtc_state *dm_crtc_state = NULL; int i; char *wr_buf = NULL; uint32_t wr_buf_size = 42; @@ -1449,6 +1484,25 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf, if (!pipe_ctx || !pipe_ctx->stream) goto done; + // Safely get CRTC state + mutex_lock(&dev->mode_config.mutex); + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + + if (connector->state == NULL) + goto unlock; + + crtc = connector->state->crtc; + if (crtc == NULL) + goto unlock; + + drm_modeset_lock(&crtc->mutex, NULL); + if (crtc->state == NULL) + goto unlock; + + dm_crtc_state = to_dm_crtc_state(crtc->state); + if (dm_crtc_state->stream == NULL) + goto unlock; + if (param[0] > 0) aconnector->dsc_settings.dsc_num_slices_h = DIV_ROUND_UP( pipe_ctx->stream->timing.h_addressable, @@ -1456,6 +1510,14 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf, else aconnector->dsc_settings.dsc_num_slices_h = 0; + dm_crtc_state->dsc_force_changed = true; + +unlock: + if (crtc) + drm_modeset_unlock(&crtc->mutex); + drm_modeset_unlock(&dev->mode_config.connection_mutex); + mutex_unlock(&dev->mode_config.mutex); + done: kfree(wr_buf); return size; @@ -1561,6 +1623,10 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, size_t size, loff_t *pos) { struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; + struct drm_connector *connector = &aconnector->base; + struct drm_device *dev = connector->dev; + struct drm_crtc *crtc = NULL; + struct dm_crtc_state *dm_crtc_state = NULL; struct pipe_ctx *pipe_ctx; int i; char *wr_buf = NULL; @@ -1603,6 +1669,25 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, if (!pipe_ctx || !pipe_ctx->stream) goto done; + // Get CRTC state + mutex_lock(&dev->mode_config.mutex); + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + + if (connector->state == NULL) + goto unlock; + + crtc = connector->state->crtc; + if (crtc == NULL) + goto unlock; + + drm_modeset_lock(&crtc->mutex, NULL); + if (crtc->state == NULL) + goto unlock; + + dm_crtc_state = to_dm_crtc_state(crtc->state); + if (dm_crtc_state->stream == NULL) + goto unlock; + if (param[0] > 0) aconnector->dsc_settings.dsc_num_slices_v = DIV_ROUND_UP( pipe_ctx->stream->timing.v_addressable, @@ -1610,6 +1695,14 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, else aconnector->dsc_settings.dsc_num_slices_v = 0; + dm_crtc_state->dsc_force_changed = true; + +unlock: + if (crtc) + drm_modeset_unlock(&crtc->mutex); + drm_modeset_unlock(&dev->mode_config.connection_mutex); + mutex_unlock(&dev->mode_config.mutex); + done: kfree(wr_buf); return size; @@ -1708,6 +1801,10 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu size_t size, loff_t *pos) { struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; + struct drm_connector *connector = &aconnector->base; + struct drm_device *dev = connector->dev; + struct drm_crtc *crtc = NULL; + struct dm_crtc_state *dm_crtc_state = NULL; struct pipe_ctx *pipe_ctx; int i; char *wr_buf = NULL; @@ -1750,8 +1847,35 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu if (!pipe_ctx || !pipe_ctx->stream) goto done; + // Get CRTC state + mutex_lock(&dev->mode_config.mutex); + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + + if (connector->state == NULL) + goto unlock; + + crtc = connector->state->crtc; + if (crtc == NULL) + goto unlock; + + drm_modeset_lock(&crtc->mutex, NULL); + if (crtc->state == NULL) + goto unlock; + + dm_crtc_state = to_dm_crtc_state(crtc->state); + if (dm_crtc_state->stream == NULL) + goto unlock; + aconnector->dsc_settings.dsc_bits_per_pixel = param[0]; + dm_crtc_state->dsc_force_changed = true; + +unlock: + if (crtc) + drm_modeset_unlock(&crtc->mutex); + drm_modeset_unlock(&dev->mode_config.connection_mutex); + mutex_unlock(&dev->mode_config.mutex); + done: kfree(wr_buf); return size; |