Commit 886876ec authored by Eryk Brol's avatar Eryk Brol Committed by Alex Deucher

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: default avatarEryk Brol <eryk.brol@amd.com>
Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3a372bed
...@@ -9120,6 +9120,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, ...@@ -9120,6 +9120,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
enum dc_status status; enum dc_status status;
int ret, i; int ret, i;
bool lock_and_validation_needed = false; bool lock_and_validation_needed = false;
struct dm_crtc_state *dm_old_crtc_state;
trace_amdgpu_dm_atomic_check_begin(state); trace_amdgpu_dm_atomic_check_begin(state);
...@@ -9162,9 +9163,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, ...@@ -9162,9 +9163,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
} }
#endif #endif
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { 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) && if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
!new_crtc_state->color_mgmt_changed && !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; continue;
if (!new_crtc_state->enable) if (!new_crtc_state->enable)
......
...@@ -438,6 +438,7 @@ struct dm_crtc_state { ...@@ -438,6 +438,7 @@ struct dm_crtc_state {
bool freesync_timing_changed; bool freesync_timing_changed;
bool freesync_vrr_info_changed; bool freesync_vrr_info_changed;
bool dsc_force_changed;
bool vrr_supported; bool vrr_supported;
struct mod_freesync_config freesync_config; struct mod_freesync_config freesync_config;
struct dc_info_packet vrr_infopacket; struct dc_info_packet vrr_infopacket;
......
...@@ -1253,6 +1253,10 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, ...@@ -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) size_t size, loff_t *pos)
{ {
struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; 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; struct pipe_ctx *pipe_ctx;
int i; int i;
char *wr_buf = NULL; char *wr_buf = NULL;
...@@ -1295,6 +1299,25 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, ...@@ -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) if (!pipe_ctx || !pipe_ctx->stream)
goto done; 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) if (param[0] == 1)
aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_ENABLE; aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_ENABLE;
else if (param[0] == 2) else if (param[0] == 2)
...@@ -1302,6 +1325,14 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, ...@@ -1302,6 +1325,14 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf,
else else
aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_DEFAULT; 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: done:
kfree(wr_buf); kfree(wr_buf);
return size; return size;
...@@ -1408,6 +1439,10 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf, ...@@ -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 amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
struct pipe_ctx *pipe_ctx; 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; int i;
char *wr_buf = NULL; char *wr_buf = NULL;
uint32_t wr_buf_size = 42; 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, ...@@ -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) if (!pipe_ctx || !pipe_ctx->stream)
goto done; 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) if (param[0] > 0)
aconnector->dsc_settings.dsc_num_slices_h = DIV_ROUND_UP( aconnector->dsc_settings.dsc_num_slices_h = DIV_ROUND_UP(
pipe_ctx->stream->timing.h_addressable, 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, ...@@ -1456,6 +1510,14 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf,
else else
aconnector->dsc_settings.dsc_num_slices_h = 0; 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: done:
kfree(wr_buf); kfree(wr_buf);
return size; return size;
...@@ -1561,6 +1623,10 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, ...@@ -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) size_t size, loff_t *pos)
{ {
struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; 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; struct pipe_ctx *pipe_ctx;
int i; int i;
char *wr_buf = NULL; char *wr_buf = NULL;
...@@ -1603,6 +1669,25 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, ...@@ -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) if (!pipe_ctx || !pipe_ctx->stream)
goto done; 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) if (param[0] > 0)
aconnector->dsc_settings.dsc_num_slices_v = DIV_ROUND_UP( aconnector->dsc_settings.dsc_num_slices_v = DIV_ROUND_UP(
pipe_ctx->stream->timing.v_addressable, 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, ...@@ -1610,6 +1695,14 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf,
else else
aconnector->dsc_settings.dsc_num_slices_v = 0; 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: done:
kfree(wr_buf); kfree(wr_buf);
return size; return size;
...@@ -1708,6 +1801,10 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu ...@@ -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) size_t size, loff_t *pos)
{ {
struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; 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; struct pipe_ctx *pipe_ctx;
int i; int i;
char *wr_buf = NULL; char *wr_buf = NULL;
...@@ -1750,8 +1847,35 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu ...@@ -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) if (!pipe_ctx || !pipe_ctx->stream)
goto done; 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]; 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: done:
kfree(wr_buf); kfree(wr_buf);
return size; return size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment