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,
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)
......
......@@ -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;
......
......@@ -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;
......
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