summaryrefslogtreecommitdiff
path: root/mali_kbase/csf/mali_kbase_csf_tl_reader.h
blob: d554d56874846c776bf7b057b468819440e70b38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
 *
 * (C) COPYRIGHT 2019-2022 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU license.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 */

#ifndef _KBASE_CSFFW_TL_READER_H_
#define _KBASE_CSFFW_TL_READER_H_

#include <linux/spinlock.h>
#include <linux/timer.h>
#include <asm/page.h>

/* The number of pages used for CSFFW trace buffer. Can be tweaked. */
#define KBASE_CSF_TL_BUFFER_NR_PAGES 128
/* CSFFW Timeline read polling minimum period in milliseconds. */
#define KBASE_CSF_TL_READ_INTERVAL_MIN 20
/* CSFFW Timeline read polling default period in milliseconds. */
#define KBASE_CSF_TL_READ_INTERVAL_DEFAULT 200
/* CSFFW Timeline read polling maximum period in milliseconds. */
#define KBASE_CSF_TL_READ_INTERVAL_MAX (60*1000)

struct firmware_trace_buffer;
struct kbase_tlstream;
struct kbase_device;

/**
 * struct kbase_ts_converter - System timestamp to CPU timestamp converter state.
 *
 * @multiplier:		Numerator of the converter's fraction.
 * @divisor:		Denominator of the converter's fraction.
 * @offset:		Converter's offset term.
 *
 * According to Generic timer spec, system timer:
 * - Increments at a fixed frequency
 * - Starts operating from zero
 *
 * Hence CPU time is a linear function of System Time.
 *
 * CPU_ts = alpha * SYS_ts + beta
 *
 * Where
 * - alpha = 10^9/SYS_ts_freq
 * - beta is calculated by two timer samples taken at the same time:
 *   beta = CPU_ts_s - SYS_ts_s * alpha
 *
 * Since alpha is a rational number, we minimizing possible
 * rounding error by simplifying the ratio. Thus alpha is stored
 * as a simple `multiplier / divisor` ratio.
 *
 */
struct kbase_ts_converter {
	u64 multiplier;
	u64 divisor;
	s64 offset;
};

/**
 * struct kbase_csf_tl_reader - CSFFW timeline reader state.
 *
 * @read_timer:        Timer used for periodical tracebufer reading.
 * @timer_interval:    Timer polling period in milliseconds.
 * @stream:            Timeline stream where to the tracebuffer content
 *                     is copied.
 * @kbdev:             KBase device.
 * @trace_buffer:      CSF Firmware timeline tracebuffer.
 * @tl_header:         CSFFW Timeline header
 * @tl_header.data:    CSFFW Timeline header content.
 * @tl_header.size:    CSFFW Timeline header size.
 * @tl_header.btc:     CSFFW Timeline header remaining bytes to copy to
 *                     the user space.
 * @ts_converter:      Timestamp converter state.
 * @got_first_event:   True, if a CSFFW timelime session has been enabled
 *                     and the first event was received.
 * @is_active:         True, if a CSFFW timelime session has been enabled.
 * @expected_event_id: The last 16 bit event ID received from CSFFW. It
 *                     is only valid when got_first_event is true.
 * @read_buffer:       Temporary buffer used for CSFFW timeline data
 *                     reading from the tracebufer.
 * @read_lock:         CSFFW timeline reader lock.
 */
struct kbase_csf_tl_reader {
	struct timer_list read_timer;
	u32 timer_interval;
	struct kbase_tlstream *stream;

	struct kbase_device *kbdev;
	struct firmware_trace_buffer *trace_buffer;
	struct {
		const char *data;
		size_t size;
		size_t btc;
	} tl_header;
	struct kbase_ts_converter ts_converter;

	bool got_first_event;
	bool is_active;
	u16 expected_event_id;

	u8 read_buffer[PAGE_SIZE * KBASE_CSF_TL_BUFFER_NR_PAGES];
	spinlock_t read_lock;
};

/**
 * kbase_csf_tl_reader_init() - Initialize CSFFW Timelime Stream Reader.
 *
 * @self:	CSFFW TL Reader instance.
 * @stream:	Destination timeline stream.
 */
void kbase_csf_tl_reader_init(struct kbase_csf_tl_reader *self,
	struct kbase_tlstream *stream);

/**
 * kbase_csf_tl_reader_term() - Terminate CSFFW Timelime Stream Reader.
 *
 * @self:	CSFFW TL Reader instance.
 */
void kbase_csf_tl_reader_term(struct kbase_csf_tl_reader *self);

/**
 *  kbase_csf_tl_reader_flush_buffer() - Flush trace from buffer into CSFFW timeline stream.
 *
 * @self:    CSFFW TL Reader instance.
 *
 * Return: Zero on success, negative error code (EBUSY) otherwise
 */
int kbase_csf_tl_reader_flush_buffer(struct kbase_csf_tl_reader *self);

/**
 * kbase_csf_tl_reader_start() - Start asynchronous copying of CSFFW timeline stream.
 *
 * @self:	CSFFW TL Reader instance.
 * @kbdev:	Kbase device.
 *
 * Return: zero on success, a negative error code otherwise.
 */
int kbase_csf_tl_reader_start(struct kbase_csf_tl_reader *self,
	struct kbase_device *kbdev);

/**
 * kbase_csf_tl_reader_stop() - Stop asynchronous copying of CSFFW timeline stream.
 *
 * @self:	CSFFW TL Reader instance.
 */
void kbase_csf_tl_reader_stop(struct kbase_csf_tl_reader *self);

#if IS_ENABLED(CONFIG_DEBUG_FS)
/**
 * kbase_csf_tl_reader_debugfs_init() - Initialize debugfs for CSFFW Timelime Stream Reader.
 *
 * @kbdev:	Kbase device.
 */
void kbase_csf_tl_reader_debugfs_init(struct kbase_device *kbdev);
#endif

/**
 * kbase_csf_tl_reader_reset() - Reset CSFFW timeline reader, it should be called before reset CSFFW.
 *
 * @self:	CSFFW TL Reader instance.
 */
void kbase_csf_tl_reader_reset(struct kbase_csf_tl_reader *self);

#endif /* _KBASE_CSFFW_TL_READER_H_ */