summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
diff options
context:
space:
mode:
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>2018-08-15 12:00:23 -0400
committerAlex Deucher <alexander.deucher@amd.com>2018-08-27 15:20:49 -0500
commit46659a83e4662ed92000ec13445b8c0ca96fd2cc (patch)
tree71f5e2fd083a41b56c86e29351d2a89ce55dcfad /drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
parent1f6010a96273c3111ecdc12aa274c932da920493 (diff)
drm/amd/display: Support reading hw state from debugfs file
[Why] Logging hardware state can be done by triggering a write to the debugfs file. It would also be useful to be able to read the hardware state from the debugfs file to be able to generate a clean log without timestamps. [How] Usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dtn_log Threading is an obvious concern when dealing with multiple debugfs operations and blocking on global state in dm or dc seems unfavorable. Adding an extra parameter for the debugfs log context state is the implementation done here. Existing code that made use of DTN_INFO and its associated macros needed to be refactored to support this. We don't know the size of the log in advance so it reallocates the log string dynamically. Once the log has been generated it's copied into the user supplied buffer for the debugfs. This allows for seeking support but it's worth nothing that unlike triggering output via dmesg the hardware state might change in-between reads if your buffer size is too small. Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Reviewed-by: Jordan Lazare <Jordan.Lazare@amd.com> Acked-by: Leo Li <sunpeng.li@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c81
1 files changed, 72 insertions, 9 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 86b63ce1dbf6..39997d977efb 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -335,28 +335,91 @@ bool dm_helpers_dp_mst_send_payload_allocation(
return true;
}
-void dm_dtn_log_begin(struct dc_context *ctx)
+void dm_dtn_log_begin(struct dc_context *ctx,
+ struct dc_log_buffer_ctx *log_ctx)
{
- pr_info("[dtn begin]\n");
+ static const char msg[] = "[dtn begin]\n";
+
+ if (!log_ctx) {
+ pr_info("%s", msg);
+ return;
+ }
+
+ dm_dtn_log_append_v(ctx, log_ctx, "%s", msg);
}
void dm_dtn_log_append_v(struct dc_context *ctx,
- const char *msg, ...)
+ struct dc_log_buffer_ctx *log_ctx,
+ const char *msg, ...)
{
- struct va_format vaf;
va_list args;
+ size_t total;
+ int n;
+
+ if (!log_ctx) {
+ /* No context, redirect to dmesg. */
+ struct va_format vaf;
+
+ vaf.fmt = msg;
+ vaf.va = &args;
+
+ va_start(args, msg);
+ pr_info("%pV", &vaf);
+ va_end(args);
+ return;
+ }
+
+ /* Measure the output. */
va_start(args, msg);
- vaf.fmt = msg;
- vaf.va = &args;
+ n = vsnprintf(NULL, 0, msg, args);
+ va_end(args);
+
+ if (n <= 0)
+ return;
+
+ /* Reallocate the string buffer as needed. */
+ total = log_ctx->pos + n + 1;
- pr_info("%pV", &vaf);
+ if (total > log_ctx->size) {
+ char *buf = (char *)kvcalloc(total, sizeof(char), GFP_KERNEL);
+
+ if (buf) {
+ memcpy(buf, log_ctx->buf, log_ctx->pos);
+ kfree(log_ctx->buf);
+
+ log_ctx->buf = buf;
+ log_ctx->size = total;
+ }
+ }
+
+ if (!log_ctx->buf)
+ return;
+
+ /* Write the formatted string to the log buffer. */
+ va_start(args, msg);
+ n = vscnprintf(
+ log_ctx->buf + log_ctx->pos,
+ log_ctx->size - log_ctx->pos,
+ msg,
+ args);
va_end(args);
+
+ if (n > 0)
+ log_ctx->pos += n;
}
-void dm_dtn_log_end(struct dc_context *ctx)
+void dm_dtn_log_end(struct dc_context *ctx,
+ struct dc_log_buffer_ctx *log_ctx)
{
- pr_info("[dtn end]\n");
+ static const char msg[] = "[dtn end]\n";
+
+ if (!log_ctx) {
+ pr_info("%s", msg);
+ return;
+ }
+
+ dm_dtn_log_append_v(ctx, log_ctx, "%s", msg);
}
bool dm_helpers_dp_mst_start_top_mgr(