summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEryk Brol <eryk.brol@amd.com>2020-06-19 14:02:38 -0400
committerAlex Deucher <alexander.deucher@amd.com>2020-08-04 17:29:27 -0400
commit5268bf136ef08c6a30d132036de3092d8219da8c (patch)
treea99f902e2053a187532a74e6fc179808d90112f3
parenta245528c598dc80fe909a5ea77372d071fd3a111 (diff)
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: Eryk Brol <eryk.brol@amd.com> Signed-off-by: Mikita Lipski <mikita.lipski@amd.com> Reviewed-by: Mikita Lipski <Mikita.Lipski@amd.com> Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c3
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h1
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c86
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c9
4 files changed, 98 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 26217e5e800d..765680b62d6a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -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
}
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 1a31473d3992..a8fff3413af3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -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 {
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 b4c470c75cbe..9260b27659e4 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
@@ -1423,6 +1423,18 @@ done:
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
};
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 4d74780f21a4..a222335133e0 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
@@ -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(