aboutsummaryrefslogtreecommitdiff
path: root/driver/mali/mali_kbase_gator_api.h
blob: 5ed069797e36f852423aa176b9caa521b8691f98 (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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/**
 * Copyright (C) ARM Limited 2014. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

#ifndef _KBASE_GATOR_API_H_
#define _KBASE_GATOR_API_H_

/**
 * @brief This file describes the API used by Gator to collect hardware counters data from a Mali device.
 */

/* This define is used by the gator kernel module compile to select which DDK
 * API calling convention to use. If not defined (legacy DDK) gator assumes
 * version 1. The version to DDK release mapping is:
 *     Version 1 API: DDK versions r1px, r2px
 *     Version 2 API: DDK versions r3px, r4px
 *     Version 3 API: DDK version r5p0 and newer
 *
 * API Usage
 * =========
 *
 * 1] Call kbase_gator_hwcnt_init_names() to return the list of short counter
 * names for the GPU present in this device.
 *
 * 2] Create a kbase_gator_hwcnt_info structure and set the counter enables for
 * the counters you want enabled. The enables can all be set for simplicity in
 * most use cases, but disabling some will let you minimize bandwidth impact.
 *
 * 3] Call kbase_gator_hwcnt_init() using the above structure, to create a
 * counter context. On successful return the DDK will have populated the
 * structure with a variety of useful information.
 *
 * 4] Call kbase_gator_hwcnt_dump_irq() to queue a non-blocking request for a
 * counter dump. If this returns a non-zero value the request has been queued,
 * otherwise the driver has been unable to do so (typically because of another
 * user of the instrumentation exists concurrently).
 *
 * 5] Call kbase_gator_hwcnt_dump_complete() to test whether the  previously
 * requested dump has been succesful. If this returns non-zero the counter dump
 * has resolved, but the value of *success must also be tested as the dump
 * may have not been successful. If it returns zero the counter dump was
 * abandoned due to the device being busy (typically because of another
 * user of the instrumentation exists concurrently).
 *
 * 6] Process the counters stored in the buffer pointed to by ...
 *
 *        kbase_gator_hwcnt_info->kernel_dump_buffer
 *
 *    In pseudo code you can find all of the counters via this approach:
 *
 *
 *        hwcnt_info # pointer to kbase_gator_hwcnt_info structure
 *        hwcnt_name # pointer to name list
 *
 *        u32 * hwcnt_data = (u32*)hwcnt_info->kernel_dump_buffer
 *
 *        # Iterate over each 64-counter block in this GPU configuration
 *        for( i = 0; i < hwcnt_info->nr_hwc_blocks; i++) {
 *            hwc_type type = hwcnt_info->hwc_layout[i];
 *
 *            # Skip reserved type blocks - they contain no counters at all
 *            if( type == RESERVED_BLOCK ) {
 *                continue;
 *            }
 *
 *            size_t name_offset = type * 64;
 *            size_t data_offset = i * 64;
 *
 *            # Iterate over the names of the counters in this block type
 *            for( j = 0; j < 64; j++) {
 *                const char * name = hwcnt_name[name_offset+j];
 *
 *                # Skip empty name strings - there is no counter here
 *                if( name[0] == '\0' ) {
 *                    continue;
 *                }
 *
 *                u32 data = hwcnt_data[data_offset+j];
 *
 *                printk( "COUNTER: %s DATA: %u\n", name, data );
 *            }
 *        }
 *
 *
 *     Note that in most implementations you typically want to either SUM or
 *     AVERAGE multiple instances of the same counter if, for example, you have
 *     multiple shader cores or multiple L2 caches. The most sensible view for
 *     analysis is to AVERAGE shader core counters, but SUM L2 cache and MMU
 *     counters.
 *
 * 7] Goto 4, repeating until you want to stop collecting counters.
 *
 * 8] Release the dump resources by calling kbase_gator_hwcnt_term().
 *
 * 9] Release the name table resources by calling kbase_gator_hwcnt_term_names().
 *    This function must only be called if init_names() returned a non-NULL value.
 **/

#define MALI_DDK_GATOR_API_VERSION 3

#if !defined(MALI_TRUE)
	#define MALI_TRUE                ((uint32_t)1)
#endif

#if !defined(MALI_FALSE)
	#define MALI_FALSE               ((uint32_t)0)
#endif

enum hwc_type {
	JM_BLOCK = 0,
	TILER_BLOCK,
	SHADER_BLOCK,
	MMU_L2_BLOCK,
	RESERVED_BLOCK
};

struct kbase_gator_hwcnt_info {

	/* Passed from Gator to kbase */

	/* the bitmask of enabled hardware counters for each counter block */
	uint16_t bitmask[4];

	/* Passed from kbase to Gator */

	/* ptr to counter dump memory */
	void *kernel_dump_buffer;

	/* size of counter dump memory */
	uint32_t size;

	/* the ID of the Mali device */
	uint32_t gpu_id;

	/* the number of shader cores in the GPU */
	uint32_t nr_cores;

	/* the number of core groups */
	uint32_t nr_core_groups;

	/* the memory layout of the performance counters */
	enum hwc_type *hwc_layout;

	/* the total number of hardware couter blocks */
	uint32_t nr_hwc_blocks;
};

/**
 * @brief Opaque block of Mali data which Gator needs to return to the API later.
 */
struct kbase_gator_hwcnt_handles;

/**
 * @brief Initialize the resources Gator needs for performance profiling.
 *
 * @param in_out_info   A pointer to a structure containing the enabled counters passed from Gator and all the Mali
 *                      specific information that will be returned to Gator. On entry Gator must have populated the
 *                      'bitmask' field with the counters it wishes to enable for each class of counter block.
 *                      Each entry in the array corresponds to a single counter class based on the "hwc_type"
 *                      enumeration, and each bit corresponds to an enable for 4 sequential counters (LSB enables
 *                      the first 4 counters in the block, and so on). See the GPU counter array as returned by
 *                      kbase_gator_hwcnt_get_names() for the index values of each counter for the curernt GPU.
 *
 * @return              Pointer to an opaque handle block on success, NULL on error.
 */
extern struct kbase_gator_hwcnt_handles *kbase_gator_hwcnt_init(struct kbase_gator_hwcnt_info *in_out_info);

/**
 * @brief Free all resources once Gator has finished using performance counters.
 *
 * @param in_out_info       A pointer to a structure containing the enabled counters passed from Gator and all the
 *                          Mali specific information that will be returned to Gator.
 * @param opaque_handles    A wrapper structure for kbase structures.
 */
extern void kbase_gator_hwcnt_term(struct kbase_gator_hwcnt_info *in_out_info, struct kbase_gator_hwcnt_handles *opaque_handles);

/**
 * @brief Poll whether a counter dump is successful.
 *
 * @param opaque_handles    A wrapper structure for kbase structures.
 * @param[out] success      Non-zero on success, zero on failure.
 *
 * @return                  Zero if the dump is still pending, non-zero if the dump has completed. Note that a
 *                          completed dump may not have dumped succesfully, so the caller must test for both
 *                          a completed and successful dump before processing counters.
 */
extern uint32_t kbase_gator_instr_hwcnt_dump_complete(struct kbase_gator_hwcnt_handles *opaque_handles, uint32_t * const success);

/**
 * @brief Request the generation of a new counter dump.
 *
 * @param opaque_handles    A wrapper structure for kbase structures.
 *
 * @return                  Zero if the hardware device is busy and cannot handle the request, non-zero otherwise.
 */
extern uint32_t kbase_gator_instr_hwcnt_dump_irq(struct kbase_gator_hwcnt_handles *opaque_handles);

/**
 * @brief This function is used to fetch the names table based on the Mali device in use.
 *
 * @param[out] total_number_of_counters The total number of counters short names in the Mali devices' list.
 *
 * @return                              Pointer to an array of strings of length *total_number_of_counters.
 */
extern const char * const *kbase_gator_hwcnt_init_names(uint32_t *total_number_of_counters);

/**
 * @brief This function is used to terminate the use of the names table.
 *
 * This function must only be called if the initial call to kbase_gator_hwcnt_init_names returned a non-NULL value.
 */
extern void kbase_gator_hwcnt_term_names(void);

#endif