diff options
author | Eryk Brol <eryk.brol@amd.com> | 2021-09-16 21:27:16 +0800 |
---|---|---|
committer | Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> | 2021-09-28 10:59:11 -0400 |
commit | 18278534c085c35adcf62f158a8d5356e5496f8d (patch) | |
tree | 77c08dfccd95a589316743ab56be3bef3bbf12e4 /lib/igt_amd.c | |
parent | cc27789ea0a79b8d052c6728509ec8dd401da347 (diff) |
tests/amdgpu: Add amd_link_settings test
[Why]
Having a test that iterates through different link
settings and performs link training with them is useful
and currently missing from IGT.
[How]
Add a link settings test and its required helper functions.
Signed-off-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Eryk Brol <eryk.brol@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Tested-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Diffstat (limited to 'lib/igt_amd.c')
-rw-r--r-- | lib/igt_amd.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/lib/igt_amd.c b/lib/igt_amd.c index 4ffe7cf2..f1bfb421 100644 --- a/lib/igt_amd.c +++ b/lib/igt_amd.c @@ -323,3 +323,122 @@ int igt_amd_trigger_hotplug(int drm_fd, char *connector_name) return 0; } + +/* + * igt_amd_read_link_settings: + * @drm_fd: DRM file descriptor + * @connector_name: The name of the connector to read the link_settings + * @lane_count: Lane count + * @link_rate: Link rate + * @link_spread: Spread spectrum + * + * The indices of @lane_count, @link_rate, and @link_spread correspond to the + * values of "Current", "Verified", "Reported", and "Preferred", respectively. + */ +void igt_amd_read_link_settings( + int drm_fd, char *connector_name, int *lane_count, int *link_rate, int *link_spread) +{ + int fd, ret; + char buf[101]; + int i = 0; + char *token_end, *val_token; + + fd = igt_debugfs_connector_dir(drm_fd, connector_name, O_RDONLY); + if (fd < 0) { + igt_info("Could not open connector %s debugfs directory\n", + connector_name); + return; + } + ret = igt_debugfs_simple_read(fd, DEBUGFS_DP_LINK_SETTINGS, buf, sizeof(buf)); + igt_assert_f(ret >= 0, "Reading %s for connector %s failed.\n", + DEBUGFS_DP_LINK_SETTINGS, connector_name); + + close(fd); + + /* Between current, verified, reported, and preferred are null terminators, + * replace them with ';' to use as the delimiter for strtok. */ + while (strlen(buf) < sizeof(buf) - 1 && buf[strlen(buf)] == '\0') + buf[strlen(buf)] = ';'; + + /* Parse values read from file. */ + for (char *token = strtok_r(buf, ";", &token_end); + token != NULL; + token = strtok_r(NULL, ";", &token_end)) + { + strtok_r(token, ": ", &val_token); + lane_count[i] = strtol(val_token, &val_token, 10); + link_rate[i] = strtol(val_token, &val_token, 10); + link_spread[i] = strtol(val_token, &val_token, 10); + i++; + + if (i > 3) return; + } +} + +/* + * igt_amd_write_link_settings: + * @drm_fd: DRM file descriptor + * @connector_name: The name of the connector to write the link_settings + * @lane_count: Lane count + * @link_rate: Link rate + * @training_type: Link training type + */ +void igt_amd_write_link_settings( + int drm_fd, char *connector_name, enum dc_lane_count lane_count, + enum dc_link_rate link_rate, enum dc_link_training_type training_type) +{ + int ls_fd, fd; + const int buf_len = 40; + char buf[buf_len]; + int wr_len = 0; + + memset(buf, '\0', sizeof(char) * buf_len); + + fd = igt_debugfs_connector_dir(drm_fd, connector_name, O_RDONLY); + igt_assert(fd >= 0); + ls_fd = openat(fd, DEBUGFS_DP_LINK_SETTINGS, O_WRONLY); + close(fd); + igt_assert(ls_fd >= 0); + + /* dp_link_settings_write expects a \n at the end or else it will + * dereference a null pointer. + */ + if (training_type == LINK_TRAINING_DEFAULT) + snprintf(buf, sizeof(buf), "%02x %02x \n", lane_count, link_rate); + else + snprintf(buf, sizeof(buf), "%02x %02x %02x \n", lane_count, + link_rate, training_type); + + wr_len = write(ls_fd, buf, strlen(buf)); + igt_assert_eq(wr_len, strlen(buf)); + + close(ls_fd); +} + +/** + * igt_amd_output_has_link_settings: check if connector has link_settings debugfs entry + * @drm_fd: DRM file descriptor + * @connector_name: The connector's name, on which we're reading the status + */ +bool igt_amd_output_has_link_settings(int drm_fd, char *connector_name) +{ + int fd; + int res; + struct stat stat; + + fd = igt_debugfs_connector_dir(drm_fd, connector_name, O_RDONLY); + if (fd < 0) { + igt_info("output %s: debugfs not found\n", connector_name); + return false; + } + + res = fstatat(fd, DEBUGFS_DP_LINK_SETTINGS, &stat, 0); + if (res != 0) { + igt_info("output %s: %s debugfs not supported\n", connector_name, DEBUGFS_DP_LINK_SETTINGS); + close(fd); + return false; + } + + close(fd); + return true; +} |