1 /* 2 * 3 * (C) COPYRIGHT 2014-2015 ARM Limited. All rights reserved. 4 * 5 * This program is free software and is provided to you under the terms of the 6 * GNU General Public License version 2 as published by the Free Software 7 * Foundation, and any use by you of this program is subject to the terms 8 * of such GNU licence. 9 * 10 * A copy of the licence is included with the program, and can also be obtained 11 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 12 * Boston, MA 02110-1301, USA. 13 * 14 */ 15 16 17 18 #ifndef _KBASE_GATOR_API_H_ 19 #define _KBASE_GATOR_API_H_ 20 21 /** 22 * @brief This file describes the API used by Gator to fetch hardware counters. 23 */ 24 25 /* This define is used by the gator kernel module compile to select which DDK 26 * API calling convention to use. If not defined (legacy DDK) gator assumes 27 * version 1. The version to DDK release mapping is: 28 * Version 1 API: DDK versions r1px, r2px 29 * Version 2 API: DDK versions r3px, r4px 30 * Version 3 API: DDK version r5p0 and newer 31 * 32 * API Usage 33 * ========= 34 * 35 * 1] Call kbase_gator_hwcnt_init_names() to return the list of short counter 36 * names for the GPU present in this device. 37 * 38 * 2] Create a kbase_gator_hwcnt_info structure and set the counter enables for 39 * the counters you want enabled. The enables can all be set for simplicity in 40 * most use cases, but disabling some will let you minimize bandwidth impact. 41 * 42 * 3] Call kbase_gator_hwcnt_init() using the above structure, to create a 43 * counter context. On successful return the DDK will have populated the 44 * structure with a variety of useful information. 45 * 46 * 4] Call kbase_gator_hwcnt_dump_irq() to queue a non-blocking request for a 47 * counter dump. If this returns a non-zero value the request has been queued, 48 * otherwise the driver has been unable to do so (typically because of another 49 * user of the instrumentation exists concurrently). 50 * 51 * 5] Call kbase_gator_hwcnt_dump_complete() to test whether the previously 52 * requested dump has been succesful. If this returns non-zero the counter dump 53 * has resolved, but the value of *success must also be tested as the dump 54 * may have not been successful. If it returns zero the counter dump was 55 * abandoned due to the device being busy (typically because of another 56 * user of the instrumentation exists concurrently). 57 * 58 * 6] Process the counters stored in the buffer pointed to by ... 59 * 60 * kbase_gator_hwcnt_info->kernel_dump_buffer 61 * 62 * In pseudo code you can find all of the counters via this approach: 63 * 64 * 65 * hwcnt_info # pointer to kbase_gator_hwcnt_info structure 66 * hwcnt_name # pointer to name list 67 * 68 * u32 * hwcnt_data = (u32*)hwcnt_info->kernel_dump_buffer 69 * 70 * # Iterate over each 64-counter block in this GPU configuration 71 * for( i = 0; i < hwcnt_info->nr_hwc_blocks; i++) { 72 * hwc_type type = hwcnt_info->hwc_layout[i]; 73 * 74 * # Skip reserved type blocks - they contain no counters at all 75 * if( type == RESERVED_BLOCK ) { 76 * continue; 77 * } 78 * 79 * size_t name_offset = type * 64; 80 * size_t data_offset = i * 64; 81 * 82 * # Iterate over the names of the counters in this block type 83 * for( j = 0; j < 64; j++) { 84 * const char * name = hwcnt_name[name_offset+j]; 85 * 86 * # Skip empty name strings - there is no counter here 87 * if( name[0] == '\0' ) { 88 * continue; 89 * } 90 * 91 * u32 data = hwcnt_data[data_offset+j]; 92 * 93 * printk( "COUNTER: %s DATA: %u\n", name, data ); 94 * } 95 * } 96 * 97 * 98 * Note that in most implementations you typically want to either SUM or 99 * AVERAGE multiple instances of the same counter if, for example, you have 100 * multiple shader cores or multiple L2 caches. The most sensible view for 101 * analysis is to AVERAGE shader core counters, but SUM L2 cache and MMU 102 * counters. 103 * 104 * 7] Goto 4, repeating until you want to stop collecting counters. 105 * 106 * 8] Release the dump resources by calling kbase_gator_hwcnt_term(). 107 * 108 * 9] Release the name table resources by calling 109 * kbase_gator_hwcnt_term_names(). This function must only be called if 110 * init_names() returned a non-NULL value. 111 **/ 112 113 #define MALI_DDK_GATOR_API_VERSION 3 114 115 enum hwc_type { 116 JM_BLOCK = 0, 117 TILER_BLOCK, 118 SHADER_BLOCK, 119 MMU_L2_BLOCK, 120 RESERVED_BLOCK 121 }; 122 123 struct kbase_gator_hwcnt_info { 124 /* Passed from Gator to kbase */ 125 126 /* the bitmask of enabled hardware counters for each counter block */ 127 uint16_t bitmask[4]; 128 129 /* Passed from kbase to Gator */ 130 131 /* ptr to counter dump memory */ 132 void *kernel_dump_buffer; 133 134 /* size of counter dump memory */ 135 uint32_t size; 136 137 /* the ID of the Mali device */ 138 uint32_t gpu_id; 139 140 /* the number of shader cores in the GPU */ 141 uint32_t nr_cores; 142 143 /* the number of core groups */ 144 uint32_t nr_core_groups; 145 146 /* the memory layout of the performance counters */ 147 enum hwc_type *hwc_layout; 148 149 /* the total number of hardware couter blocks */ 150 uint32_t nr_hwc_blocks; 151 }; 152 153 /** 154 * @brief Opaque block of Mali data which Gator needs to return to the API later. 155 */ 156 struct kbase_gator_hwcnt_handles; 157 158 /** 159 * @brief Initialize the resources Gator needs for performance profiling. 160 * 161 * @param in_out_info A pointer to a structure containing the enabled counters passed from Gator and all the Mali 162 * specific information that will be returned to Gator. On entry Gator must have populated the 163 * 'bitmask' field with the counters it wishes to enable for each class of counter block. 164 * Each entry in the array corresponds to a single counter class based on the "hwc_type" 165 * enumeration, and each bit corresponds to an enable for 4 sequential counters (LSB enables 166 * the first 4 counters in the block, and so on). See the GPU counter array as returned by 167 * kbase_gator_hwcnt_get_names() for the index values of each counter for the curernt GPU. 168 * 169 * @return Pointer to an opaque handle block on success, NULL on error. 170 */ 171 extern struct kbase_gator_hwcnt_handles *kbase_gator_hwcnt_init(struct kbase_gator_hwcnt_info *in_out_info); 172 173 /** 174 * @brief Free all resources once Gator has finished using performance counters. 175 * 176 * @param in_out_info A pointer to a structure containing the enabled counters passed from Gator and all the 177 * Mali specific information that will be returned to Gator. 178 * @param opaque_handles A wrapper structure for kbase structures. 179 */ 180 extern void kbase_gator_hwcnt_term(struct kbase_gator_hwcnt_info *in_out_info, struct kbase_gator_hwcnt_handles *opaque_handles); 181 182 /** 183 * @brief Poll whether a counter dump is successful. 184 * 185 * @param opaque_handles A wrapper structure for kbase structures. 186 * @param[out] success Non-zero on success, zero on failure. 187 * 188 * @return Zero if the dump is still pending, non-zero if the dump has completed. Note that a 189 * completed dump may not have dumped succesfully, so the caller must test for both 190 * a completed and successful dump before processing counters. 191 */ 192 extern uint32_t kbase_gator_instr_hwcnt_dump_complete(struct kbase_gator_hwcnt_handles *opaque_handles, uint32_t * const success); 193 194 /** 195 * @brief Request the generation of a new counter dump. 196 * 197 * @param opaque_handles A wrapper structure for kbase structures. 198 * 199 * @return Zero if the hardware device is busy and cannot handle the request, non-zero otherwise. 200 */ 201 extern uint32_t kbase_gator_instr_hwcnt_dump_irq(struct kbase_gator_hwcnt_handles *opaque_handles); 202 203 /** 204 * @brief This function is used to fetch the names table based on the Mali device in use. 205 * 206 * @param[out] total_counters The total number of counters short names in the Mali devices' list. 207 * 208 * @return Pointer to an array of strings of length *total_counters. 209 */ 210 extern const char * const *kbase_gator_hwcnt_init_names(uint32_t *total_counters); 211 212 /** 213 * @brief This function is used to terminate the use of the names table. 214 * 215 * This function must only be called if the initial call to kbase_gator_hwcnt_init_names returned a non-NULL value. 216 */ 217 extern void kbase_gator_hwcnt_term_names(void); 218 219 #endif 220