aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/4901-drm-amd-display-set-read-link-rate-and-lane-count-th.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/4901-drm-amd-display-set-read-link-rate-and-lane-count-th.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/4901-drm-amd-display-set-read-link-rate-and-lane-count-th.patch323
1 files changed, 323 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/4901-drm-amd-display-set-read-link-rate-and-lane-count-th.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/4901-drm-amd-display-set-read-link-rate-and-lane-count-th.patch
new file mode 100644
index 00000000..b98a39e9
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/4901-drm-amd-display-set-read-link-rate-and-lane-count-th.patch
@@ -0,0 +1,323 @@
+From b043cb5f0eda885e7dff7b8f614b74a1609925d6 Mon Sep 17 00:00:00 2001
+From: Hersen Wu <hersenxs.wu@amd.com>
+Date: Fri, 15 Jun 2018 14:25:48 -0400
+Subject: [PATCH 4901/5725] drm/amd/display: set-read link rate and lane count
+ through debugfs
+
+ function description
+ get/ set DP configuration: lane_count, link_rate, spread_spectrum
+
+ valid lane count value: 1, 2, 4
+ valid link rate value:
+ 06h = 1.62Gbps per lane
+ 0Ah = 2.7Gbps per lane
+ 0Ch = 3.24Gbps per lane
+ 14h = 5.4Gbps per lane
+ 1Eh = 8.1Gbps per lane
+
+ debugfs is located at /sys/kernel/debug/dri/0/DP-x/link_settings
+
+ --- to get dp configuration
+
+ xxd -l 300 phy_settings
+
+ It will list current, verified, reported, preferred dp configuration.
+ current -- for current video mode
+ verified --- maximum configuration which pass link training
+ reported --- DP rx report caps (DPCD register offset 0, 1 2)
+ preferred --- user force settings
+
+ --- set (or force) dp configuration
+
+ echo <lane_count> <link_rate>
+
+ for example, to force to 2 lane, 2.7GHz,
+ echo 4 0xa > link_settings
+
+ spread_spectrum could not be changed dynamically.
+
+ in case invalid lane count, link rate are force, no hw programming will be
+ done. please check link settings after force operation to see if HW get
+ programming.
+
+ xxd -l 300 link_settings
+
+ check current and preferred settings.
+
+Signed-off-by: Hersen Wu <hersenxs.wu@amd.com>
+Reviewed-by: Hersen Wu <hersenxs.wu@amd.com>
+Acked-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 227 ++++++++++++++++++---
+ 1 file changed, 196 insertions(+), 31 deletions(-)
+
+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 cf5ea69..9ff8833 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
+@@ -26,38 +26,211 @@
+ #include <linux/debugfs.h>
+
+ #include "dc.h"
+-#include "dc_link.h"
+
+ #include "amdgpu.h"
+ #include "amdgpu_dm.h"
+ #include "amdgpu_dm_debugfs.h"
+
+-static ssize_t dp_link_rate_debugfs_read(struct file *f, char __user *buf,
++/* function description
++ * get/ set DP configuration: lane_count, link_rate, spread_spectrum
++ *
++ * valid lane count value: 1, 2, 4
++ * valid link rate value:
++ * 06h = 1.62Gbps per lane
++ * 0Ah = 2.7Gbps per lane
++ * 0Ch = 3.24Gbps per lane
++ * 14h = 5.4Gbps per lane
++ * 1Eh = 8.1Gbps per lane
++ *
++ * debugfs is located at /sys/kernel/debug/dri/0/DP-x/link_settings
++ *
++ * --- to get dp configuration
++ *
++ * xxd -l 300 phy_settings
++ *
++ * It will list current, verified, reported, preferred dp configuration.
++ * current -- for current video mode
++ * verified --- maximum configuration which pass link training
++ * reported --- DP rx report caps (DPCD register offset 0, 1 2)
++ * preferred --- user force settings
++ *
++ * --- set (or force) dp configuration
++ *
++ * echo <lane_count> <link_rate>
++ *
++ * for example, to force to 2 lane, 2.7GHz,
++ * echo 4 0xa > link_settings
++ *
++ * spread_spectrum could not be changed dynamically.
++ *
++ * in case invalid lane count, link rate are force, no hw programming will be
++ * done. please check link settings after force operation to see if HW get
++ * programming.
++ *
++ * xxd -l 300 link_settings
++ *
++ * check current and preferred settings.
++ *
++ */
++static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
+ size_t size, loff_t *pos)
+ {
+- /* TODO: create method to read link rate */
+- return 1;
+-}
++ struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
++ struct dc_link *link = connector->dc_link;
++ char *rd_buf = NULL;
++ char *rd_buf_ptr = NULL;
++ uint32_t rd_buf_size = 320;
++ int bytes_to_user;
++ uint8_t str_len = 0;
++ int r;
+
+-static ssize_t dp_link_rate_debugfs_write(struct file *f, const char __user *buf,
+- size_t size, loff_t *pos)
+-{
+- /* TODO: create method to write link rate */
+- return 1;
+-}
++ if (size == 0)
++ return 0;
+
+-static ssize_t dp_lane_count_debugfs_read(struct file *f, char __user *buf,
+- size_t size, loff_t *pos)
+-{
+- /* TODO: create method to read lane count */
+- return 1;
++ rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
++ if (!rd_buf)
++ return 0;
++
++ rd_buf_ptr = rd_buf;
++
++ str_len = strlen("Current: %d %d %d ");
++ snprintf(rd_buf_ptr, str_len, "Current: %d %d %d ",
++ link->cur_link_settings.lane_count,
++ link->cur_link_settings.link_rate,
++ link->cur_link_settings.link_spread);
++ rd_buf_ptr = rd_buf_ptr + str_len;
++
++ str_len = strlen("Verified: %d %d %d ");
++ snprintf(rd_buf_ptr, str_len, "Verified: %d %d %d ",
++ link->verified_link_cap.lane_count,
++ link->verified_link_cap.link_rate,
++ link->verified_link_cap.link_spread);
++ rd_buf_ptr = rd_buf_ptr + str_len;
++
++ str_len = strlen("Reported: %d %d %d ");
++ snprintf(rd_buf_ptr, str_len, "Reported: %d %d %d ",
++ link->reported_link_cap.lane_count,
++ link->reported_link_cap.link_rate,
++ link->reported_link_cap.link_spread);
++ rd_buf_ptr = rd_buf_ptr + str_len;
++
++ str_len = strlen("Preferred: %d %d %d ");
++ snprintf(rd_buf_ptr, str_len, "Preferred: %d %d %d ",
++ link->preferred_link_setting.lane_count,
++ link->preferred_link_setting.link_rate,
++ link->preferred_link_setting.link_spread);
++
++ r = copy_to_user(buf, rd_buf, rd_buf_size);
++
++ bytes_to_user = rd_buf_size - r;
++
++ if (r > rd_buf_size) {
++ bytes_to_user = 0;
++ DRM_DEBUG_DRIVER("data not copy to user");
++ }
++
++ kfree(rd_buf);
++ return bytes_to_user;
+ }
+
+-static ssize_t dp_lane_count_debugfs_write(struct file *f, const char __user *buf,
++static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos)
+ {
+- /* TODO: create method to write lane count */
+- return 1;
++ struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
++ struct dc_link *link = connector->dc_link;
++ struct dc *dc = (struct dc *)link->dc;
++ struct dc_link_settings prefer_link_settings;
++ char *wr_buf = NULL;
++ char *wr_buf_ptr = NULL;
++ uint32_t wr_buf_size = 40;
++ int r;
++ int bytes_from_user;
++ char *sub_str;
++ /* 0: lane_count; 1: link_rate */
++ uint8_t param_index = 0;
++ long param[2];
++ const char delimiter[3] = {' ', '\n', '\0'};
++ bool valid_input = false;
++
++ if (size == 0)
++ return 0;
++
++ wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
++ if (!wr_buf)
++ return 0;
++ wr_buf_ptr = wr_buf;
++
++ r = copy_from_user(wr_buf_ptr, buf, wr_buf_size);
++
++ /* r is bytes not be copied */
++ if (r >= wr_buf_size) {
++ kfree(wr_buf);
++ DRM_DEBUG_DRIVER("user data not read\n");
++ return 0;
++ }
++
++ bytes_from_user = wr_buf_size - r;
++
++ while (isspace(*wr_buf_ptr))
++ wr_buf_ptr++;
++
++ while ((*wr_buf_ptr != '\0') && (param_index < 2)) {
++
++ sub_str = strsep(&wr_buf_ptr, delimiter);
++
++ r = kstrtol(sub_str, 16, &param[param_index]);
++
++ if (r)
++ DRM_DEBUG_DRIVER(" -EINVAL convert error happens!\n");
++
++ param_index++;
++ while (isspace(*wr_buf_ptr))
++ wr_buf_ptr++;
++ }
++
++ DRM_DEBUG_DRIVER("Lane_count: %lx\n", param[0]);
++ DRM_DEBUG_DRIVER("link_rate: %lx\n", param[1]);
++
++ switch (param[0]) {
++ case LANE_COUNT_ONE:
++ case LANE_COUNT_TWO:
++ case LANE_COUNT_FOUR:
++ valid_input = true;
++ break;
++ default:
++ break;
++ }
++
++ switch (param[1]) {
++ case LINK_RATE_LOW:
++ case LINK_RATE_HIGH:
++ case LINK_RATE_RBR2:
++ case LINK_RATE_HIGH2:
++ case LINK_RATE_HIGH3:
++ valid_input = true;
++ break;
++ default:
++ break;
++ }
++
++ if (!valid_input) {
++ kfree(wr_buf);
++ DRM_DEBUG_DRIVER("Invalid Input value exceed No HW will be programmed\n");
++ return bytes_from_user;
++ }
++
++ /* save user force lane_count, link_rate to preferred settings
++ * spread spectrum will not be changed
++ */
++ prefer_link_settings.link_spread = link->cur_link_settings.link_spread;
++ prefer_link_settings.lane_count = param[0];
++ prefer_link_settings.link_rate = param[1];
++
++ dc_link_set_preferred_link_settings(dc, &prefer_link_settings, link);
++
++ kfree(wr_buf);
++
++ return bytes_from_user;
+ }
+
+ static ssize_t dp_voltage_swing_debugfs_read(struct file *f, char __user *buf,
+@@ -102,17 +275,10 @@ static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __us
+ return 1;
+ }
+
+-static const struct file_operations dp_link_rate_fops = {
+- .owner = THIS_MODULE,
+- .read = dp_link_rate_debugfs_read,
+- .write = dp_link_rate_debugfs_write,
+- .llseek = default_llseek
+-};
+-
+-static const struct file_operations dp_lane_count_fops = {
++static const struct file_operations dp_link_settings_debugfs_fops = {
+ .owner = THIS_MODULE,
+- .read = dp_lane_count_debugfs_read,
+- .write = dp_lane_count_debugfs_write,
++ .read = dp_link_settings_read,
++ .write = dp_link_settings_write,
+ .llseek = default_llseek
+ };
+
+@@ -141,8 +307,7 @@ static const struct {
+ char *name;
+ const struct file_operations *fops;
+ } dp_debugfs_entries[] = {
+- {"link_rate", &dp_link_rate_fops},
+- {"lane_count", &dp_lane_count_fops},
++ {"link_settings", &dp_link_settings_debugfs_fops},
+ {"voltage_swing", &dp_voltage_swing_fops},
+ {"pre_emphasis", &dp_pre_emphasis_fops},
+ {"phy_test_pattern", &dp_phy_test_pattern_fops}
+--
+2.7.4
+