From 07ddc5aaad9a89a758cb5fe247c06d845b025e65 Mon Sep 17 00:00:00 2001 From: seshendra Date: Tue, 3 Sep 2019 10:47:41 -0700 Subject: gpu: nvgpu: Enabling/disabling FECS trace support - To enable FECS trace support, nvgpu should set the MSB of the read pointer (MAILBOX1). - The ucode will check if the feature is enabled/disabled before writing a record into the circular buffer. If the feature is disabled, it will not write the record. - If the feature is enabled and the buffer is not allocated, HW will throw a page fault error. Bug 2459186 Bug 200542611 Change-Id: I6f181643737d1cf1bda02077eaa714a3f4ef3d8c Signed-off-by: seshendra Reviewed-on: https://git-master.nvidia.com/r/2189250 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c | 63 +++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c index 6b384c89..11f1169b 100644 --- a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -362,6 +362,11 @@ int gk20a_fecs_trace_poll(struct gk20a *g) /* Ensure all FECS writes have made it to SYSMEM */ g->ops.mm.fb_flush(g); + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* Bits 30:0 of MAILBOX1 represents actual read pointer value */ + read = read & (~(BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT))); + } + while (read != write) { cnt = gk20a_fecs_trace_ring_read(g, read); if (cnt <= 0) @@ -371,6 +376,15 @@ int gk20a_fecs_trace_poll(struct gk20a *g) read = (read + 1) & (GK20A_FECS_TRACE_NUM_RECORDS - 1); } + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* + * In the next step, read pointer is going to be updated. + * So, MSB of read pointer should be set back to 1. This will + * keep FECS trace enabled. + */ + read = read | (BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT)); + } + /* ensure FECS records has been updated before incrementing read index */ nvgpu_wmb(); gk20a_fecs_trace_set_read_index(g, read); @@ -606,8 +620,30 @@ int gk20a_fecs_trace_enable(struct gk20a *g) if (g->ops.fecs_trace.flush) g->ops.fecs_trace.flush(g); write = gk20a_fecs_trace_get_write_index(g); + + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* + * For enabling FECS trace support, MAILBOX1's MSB + * (Bit 31:31) should be set to 1. Bits 30:0 represents + * actual pointer value. + */ + write = write | + (BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT)); + } gk20a_fecs_trace_set_read_index(g, write); + /* + * FECS ucode does a priv holdoff around the assertion of + * context reset. So, pri transactions (e.g. mailbox1 register + * write) might fail due to this. Hence, do write with ack + * i.e. write and read it back to make sure write happened for + * mailbox1. + */ + while (gk20a_fecs_trace_get_read_index(g) != write) { + nvgpu_log(g, gpu_dbg_ctxsw, "mailbox1 update failed"); + gk20a_fecs_trace_set_read_index(g, write); + } + err = nvgpu_thread_create(&trace->poll_task, g, gk20a_fecs_trace_periodic_polling, __func__); if (err) { @@ -622,10 +658,35 @@ int gk20a_fecs_trace_enable(struct gk20a *g) int gk20a_fecs_trace_disable(struct gk20a *g) { struct gk20a_fecs_trace *trace = g->fecs_trace; + int read = 0; if (nvgpu_thread_is_running(&trace->poll_task)) nvgpu_thread_stop(&trace->poll_task); + if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { + /* + * For disabling FECS trace support, MAILBOX1's MSB + * (Bit 31:31) should be set to 0. + */ + read = gk20a_fecs_trace_get_read_index(g) & + (~(BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT))); + + gk20a_fecs_trace_set_read_index(g, read); + + /* + * FECS ucode does a priv holdoff around the assertion + * of context reset. So, pri transactions (e.g. + * mailbox1 register write) might fail due to this. + * Hence, do write with ack i.e. write and read it back + * to make sure write happened for mailbox1. + */ + while (gk20a_fecs_trace_get_read_index(g) != read) { + nvgpu_log(g, gpu_dbg_ctxsw, + "mailbox1 update failed"); + gk20a_fecs_trace_set_read_index(g, read); + } + } + return -EPERM; } -- cgit v1.2.2