1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
2 /* Copyright (c) 2023 Imagination Technologies Ltd. */
4 #include "pvr_device.h"
6 #include "pvr_rogue_fwif.h"
7 #include "pvr_fw_trace.h"
9 #include <drm/drm_file.h>
11 #include <linux/build_bug.h>
12 #include <linux/dcache.h>
13 #include <linux/sysfs.h>
14 #include <linux/types.h>
17 tracebuf_ctrl_init(void *cpu_ptr, void *priv)
19 struct rogue_fwif_tracebuf *tracebuf_ctrl = cpu_ptr;
20 struct pvr_fw_trace *fw_trace = priv;
23 tracebuf_ctrl->tracebuf_size_in_dwords = ROGUE_FW_TRACE_BUF_DEFAULT_SIZE_IN_DWORDS;
24 tracebuf_ctrl->tracebuf_flags = 0;
26 if (fw_trace->group_mask)
27 tracebuf_ctrl->log_type = fw_trace->group_mask | ROGUE_FWIF_LOG_TYPE_TRACE;
29 tracebuf_ctrl->log_type = ROGUE_FWIF_LOG_TYPE_NONE;
31 for (thread_nr = 0; thread_nr < ARRAY_SIZE(fw_trace->buffers); thread_nr++) {
32 struct rogue_fwif_tracebuf_space *tracebuf_space =
33 &tracebuf_ctrl->tracebuf[thread_nr];
34 struct pvr_fw_trace_buffer *trace_buffer = &fw_trace->buffers[thread_nr];
36 pvr_fw_object_get_fw_addr(trace_buffer->buf_obj,
37 &tracebuf_space->trace_buffer_fw_addr);
39 tracebuf_space->trace_buffer = trace_buffer->buf;
40 tracebuf_space->trace_pointer = 0;
44 int pvr_fw_trace_init(struct pvr_device *pvr_dev)
46 struct pvr_fw_trace *fw_trace = &pvr_dev->fw_dev.fw_trace;
47 struct drm_device *drm_dev = from_pvr_device(pvr_dev);
51 for (thread_nr = 0; thread_nr < ARRAY_SIZE(fw_trace->buffers); thread_nr++) {
52 struct pvr_fw_trace_buffer *trace_buffer = &fw_trace->buffers[thread_nr];
55 pvr_fw_object_create_and_map(pvr_dev,
56 ROGUE_FW_TRACE_BUF_DEFAULT_SIZE_IN_DWORDS *
57 sizeof(*trace_buffer->buf),
58 PVR_BO_FW_FLAGS_DEVICE_UNCACHED |
59 PVR_BO_FW_NO_CLEAR_ON_RESET,
60 NULL, NULL, &trace_buffer->buf_obj);
61 if (IS_ERR(trace_buffer->buf)) {
62 drm_err(drm_dev, "Unable to allocate trace buffer\n");
63 err = PTR_ERR(trace_buffer->buf);
64 trace_buffer->buf = NULL;
69 /* TODO: Provide control of group mask. */
70 fw_trace->group_mask = 0;
72 fw_trace->tracebuf_ctrl =
73 pvr_fw_object_create_and_map(pvr_dev,
74 sizeof(*fw_trace->tracebuf_ctrl),
75 PVR_BO_FW_FLAGS_DEVICE_UNCACHED |
76 PVR_BO_FW_NO_CLEAR_ON_RESET,
77 tracebuf_ctrl_init, fw_trace,
78 &fw_trace->tracebuf_ctrl_obj);
79 if (IS_ERR(fw_trace->tracebuf_ctrl)) {
80 drm_err(drm_dev, "Unable to allocate trace buffer control structure\n");
81 err = PTR_ERR(fw_trace->tracebuf_ctrl);
85 BUILD_BUG_ON(ARRAY_SIZE(fw_trace->tracebuf_ctrl->tracebuf) !=
86 ARRAY_SIZE(fw_trace->buffers));
88 for (thread_nr = 0; thread_nr < ARRAY_SIZE(fw_trace->buffers); thread_nr++) {
89 struct rogue_fwif_tracebuf_space *tracebuf_space =
90 &fw_trace->tracebuf_ctrl->tracebuf[thread_nr];
91 struct pvr_fw_trace_buffer *trace_buffer = &fw_trace->buffers[thread_nr];
93 trace_buffer->tracebuf_space = tracebuf_space;
99 for (thread_nr = 0; thread_nr < ARRAY_SIZE(fw_trace->buffers); thread_nr++) {
100 struct pvr_fw_trace_buffer *trace_buffer = &fw_trace->buffers[thread_nr];
102 if (trace_buffer->buf)
103 pvr_fw_object_unmap_and_destroy(trace_buffer->buf_obj);
109 void pvr_fw_trace_fini(struct pvr_device *pvr_dev)
111 struct pvr_fw_trace *fw_trace = &pvr_dev->fw_dev.fw_trace;
114 for (thread_nr = 0; thread_nr < ARRAY_SIZE(fw_trace->buffers); thread_nr++) {
115 struct pvr_fw_trace_buffer *trace_buffer = &fw_trace->buffers[thread_nr];
117 pvr_fw_object_unmap_and_destroy(trace_buffer->buf_obj);
119 pvr_fw_object_unmap_and_destroy(fw_trace->tracebuf_ctrl_obj);