/*
|
*
|
* (C) COPYRIGHT 2014-2015 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 licence.
|
*
|
* A copy of the licence is included with the program, and can also be obtained
|
* from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
* Boston, MA 02110-1301, USA.
|
*
|
*/
|
|
|
|
#ifndef _KBASE_GATOR_API_H_
|
#define _KBASE_GATOR_API_H_
|
|
/**
|
* @brief This file describes the API used by Gator to fetch hardware counters.
|
*/
|
|
/* 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
|
|
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_counters The total number of counters short names in the Mali devices' list.
|
*
|
* @return Pointer to an array of strings of length *total_counters.
|
*/
|
extern const char * const *kbase_gator_hwcnt_init_names(uint32_t *total_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
|