Commit 5268bf13 authored by Eryk Brol's avatar Eryk Brol Committed by Alex Deucher

drm/amd/display: DSC Bit target rate debugfs write entry

[Why]
We need to be able to specify bits per pixel for DSC on any
connector.

[How]
Overwrite computed DSC target rate in dsc_cfg, with requested value.
Overwrites for both SST and MST connectors, but in different places, but the process is identical. Overwrites only if DSC is decided to be enabled on that connector.
Signed-off-by: default avatarEryk Brol <eryk.brol@amd.com>
Signed-off-by: default avatarMikita Lipski <mikita.lipski@amd.com>
Reviewed-by: default avatarMikita Lipski <Mikita.Lipski@amd.com>
Acked-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a245528c
......@@ -4678,6 +4678,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_slice_height)
stream->timing.dsc_cfg.num_slices_v = DIV_ROUND_UP(stream->timing.v_addressable,
aconnector->dsc_settings.dsc_slice_height);
if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_bits_per_pixel)
stream->timing.dsc_cfg.bits_per_pixel = aconnector->dsc_settings.dsc_bits_per_pixel;
}
#endif
}
......
......@@ -346,6 +346,7 @@ struct dsc_preferred_settings {
bool dsc_clock_en;
uint32_t dsc_slice_width;
uint32_t dsc_slice_height;
uint32_t dsc_bits_per_pixel;
};
struct amdgpu_dm_connector {
......
......@@ -1423,6 +1423,18 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf,
return size;
}
/* function: read DSC target rate on the connector in bits per pixel
*
* The read function: dp_dsc_bits_per_pixel_read
* returns target rate of compression in bits per pixel
* The return is an integer: 0 or other positive integer
*
* Access it with the following command:
*
* cat /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
*
* 0 - means that DSC is disabled
*/
static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
size_t size, loff_t *pos)
{
......@@ -1480,6 +1492,79 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
return result;
}
/* function: write DSC target rate in bits per pixel
*
* The write function: dp_dsc_bits_per_pixel_write
* overwrites automatically generated DSC configuration
* of DSC target bit rate.
*
* Also the user has to write bpp in hexidecimal
* rather than in decimal.
*
* Writing DSC settings is done with the following command:
* - To force overwrite rate (example sets to 256 bpp x 1/16):
*
* echo 0x100 > /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
*
* - To stop overwriting and let driver find the optimal rate,
* set the rate to zero:
*
* echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
*
*/
static ssize_t dp_dsc_bits_per_pixel_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 pipe_ctx *pipe_ctx;
int i;
char *wr_buf = NULL;
uint32_t wr_buf_size = 42;
int max_param_num = 1;
uint8_t param_nums = 0;
long param[1] = {0};
if (size == 0)
return -EINVAL;
wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
if (!wr_buf) {
DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
return -ENOSPC;
}
if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
(long *)param, buf,
max_param_num,
&param_nums)) {
kfree(wr_buf);
return -EINVAL;
}
if (param_nums <= 0) {
DRM_DEBUG_DRIVER("user data not be read\n");
kfree(wr_buf);
return -EINVAL;
}
for (i = 0; i < MAX_PIPES; i++) {
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
if (pipe_ctx && pipe_ctx->stream &&
pipe_ctx->stream->link == aconnector->dc_link)
break;
}
if (!pipe_ctx || !pipe_ctx->stream)
goto done;
aconnector->dsc_settings.dsc_bits_per_pixel = param[0];
done:
kfree(wr_buf);
return size;
}
static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
size_t size, loff_t *pos)
{
......@@ -1739,6 +1824,7 @@ static const struct file_operations dp_dsc_slice_height_debugfs_fops = {
static const struct file_operations dp_dsc_bits_per_pixel_debugfs_fops = {
.owner = THIS_MODULE,
.read = dp_dsc_bits_per_pixel_read,
.write = dp_dsc_bits_per_pixel_write,
.llseek = default_llseek
};
......
......@@ -453,6 +453,7 @@ struct dsc_mst_fairness_params {
bool clock_overwrite;
uint32_t slice_width_overwrite;
uint32_t slice_height_overwrite;
uint32_t bpp_overwrite;
};
struct dsc_mst_fairness_vars {
......@@ -486,7 +487,12 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p
params[i].timing,
&params[i].timing->dsc_cfg)) {
params[i].timing->flags.DSC = 1;
params[i].timing->dsc_cfg.bits_per_pixel = vars[i].bpp_x16;
if (params[i].bpp_overwrite)
params[i].timing->dsc_cfg.bits_per_pixel = params[i].bpp_overwrite;
else
params[i].timing->dsc_cfg.bits_per_pixel = vars[i].bpp_x16;
if (params[i].slice_width_overwrite)
params[i].timing->dsc_cfg.num_slices_h = DIV_ROUND_UP(
params[i].timing->h_addressable,
......@@ -714,6 +720,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state,
debugfs_overwrite = true;
params[count].slice_width_overwrite = aconnector->dsc_settings.dsc_slice_width;
params[count].slice_height_overwrite = aconnector->dsc_settings.dsc_slice_height;
params[count].bpp_overwrite = aconnector->dsc_settings.dsc_bits_per_pixel;
params[count].compression_possible = stream->sink->dsc_caps.dsc_dec_caps.is_dsc_supported;
dc_dsc_get_policy_for_timing(params[count].timing, &dsc_policy);
if (!dc_dsc_compute_bandwidth_range(
......
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