diff options
Diffstat (limited to 'driver/gator_events_mali_t6xx_hw.c')
-rw-r--r-- | driver/gator_events_mali_t6xx_hw.c | 183 |
1 files changed, 152 insertions, 31 deletions
diff --git a/driver/gator_events_mali_t6xx_hw.c b/driver/gator_events_mali_t6xx_hw.c index dfbc91f..3a072bb 100644 --- a/driver/gator_events_mali_t6xx_hw.c +++ b/driver/gator_events_mali_t6xx_hw.c @@ -16,7 +16,10 @@ #include <asm/io.h> /* Mali T6xx DDK includes */ -#ifdef MALI_DIR_MIDGARD +#if defined(MALI_SIMPLE_API) +/* Header with wrapper functions to kbase structures and functions */ +#include "mali/mali_dd_gator_api.h" +#elif defined(MALI_DIR_MIDGARD) /* New DDK Directory structure with kernel/drivers/gpu/arm/midgard*/ #include "mali_linux_trace.h" #include "mali_kbase.h" @@ -28,37 +31,49 @@ #include "kbase/src/linux/mali_kbase_mem_linux.h" #endif -#include "gator_events_mali_common.h" - /* If API version is not specified then assume API version 1. */ #ifndef MALI_DDK_GATOR_API_VERSION #define MALI_DDK_GATOR_API_VERSION 1 #endif -#if (MALI_DDK_GATOR_API_VERSION != 1) && (MALI_DDK_GATOR_API_VERSION != 2) -#error MALI_DDK_GATOR_API_VERSION is invalid (must be 1 for r1/r2 DDK, or 2 for r3 DDK). +#if (MALI_DDK_GATOR_API_VERSION != 1) && (MALI_DDK_GATOR_API_VERSION != 2) && (MALI_DDK_GATOR_API_VERSION != 3) +#error MALI_DDK_GATOR_API_VERSION is invalid (must be 1 for r1/r2 DDK, or 2 for r3 DDK, or 3 for r? DDK). #endif +#include "gator_events_mali_common.h" + /* * Mali-T6xx */ +#if MALI_DDK_GATOR_API_VERSION == 3 +typedef uint32_t kbase_dd_instr_hwcnt_dump_irq_type(struct mali_dd_hwcnt_handles *); +typedef uint32_t kbase_dd_instr_hwcnt_dump_complete_type(struct mali_dd_hwcnt_handles *, uint32_t *); +typedef struct mali_dd_hwcnt_handles* mali_dd_hwcnt_init_type(struct mali_dd_hwcnt_info *); +typedef void mali_dd_hwcnt_clear_type(struct mali_dd_hwcnt_info *, struct mali_dd_hwcnt_handles *); + +static kbase_dd_instr_hwcnt_dump_irq_type *kbase_dd_instr_hwcnt_dump_irq_symbol; +static kbase_dd_instr_hwcnt_dump_complete_type *kbase_dd_instr_hwcnt_dump_complete_symbol; +static mali_dd_hwcnt_init_type *mali_dd_hwcnt_init_symbol; +static mali_dd_hwcnt_clear_type *mali_dd_hwcnt_clear_symbol; + +#else typedef struct kbase_device *kbase_find_device_type(int); -typedef kbase_context *kbase_create_context_type(kbase_device *); -typedef void kbase_destroy_context_type(kbase_context *); +typedef struct kbase_context *kbase_create_context_type(struct kbase_device *); +typedef void kbase_destroy_context_type(struct kbase_context *); #if MALI_DDK_GATOR_API_VERSION == 1 -typedef void *kbase_va_alloc_type(kbase_context *, u32); -typedef void kbase_va_free_type(kbase_context *, void *); +typedef void *kbase_va_alloc_type(struct kbase_context *, u32); +typedef void kbase_va_free_type(struct kbase_context *, void *); #elif MALI_DDK_GATOR_API_VERSION == 2 -typedef void *kbase_va_alloc_type(kbase_context *, u32, kbase_hwc_dma_mapping * handle); -typedef void kbase_va_free_type(kbase_context *, kbase_hwc_dma_mapping * handle); +typedef void *kbase_va_alloc_type(struct kbase_context *, u32, kbase_hwc_dma_mapping * handle); +typedef void kbase_va_free_type(struct kbase_context *, kbase_hwc_dma_mapping * handle); #endif -typedef mali_error kbase_instr_hwcnt_enable_type(kbase_context *, kbase_uk_hwcnt_setup *); -typedef mali_error kbase_instr_hwcnt_disable_type(kbase_context *); -typedef mali_error kbase_instr_hwcnt_clear_type(kbase_context *); -typedef mali_error kbase_instr_hwcnt_dump_irq_type(kbase_context *); -typedef mali_bool kbase_instr_hwcnt_dump_complete_type(kbase_context *, mali_bool *); +typedef mali_error kbase_instr_hwcnt_enable_type(struct kbase_context *, struct kbase_uk_hwcnt_setup *); +typedef mali_error kbase_instr_hwcnt_disable_type(struct kbase_context *); +typedef mali_error kbase_instr_hwcnt_clear_type(struct kbase_context *); +typedef mali_error kbase_instr_hwcnt_dump_irq_type(struct kbase_context *); +typedef mali_bool kbase_instr_hwcnt_dump_complete_type(struct kbase_context *, mali_bool *); static kbase_find_device_type *kbase_find_device_symbol; static kbase_create_context_type *kbase_create_context_symbol; @@ -70,6 +85,7 @@ static kbase_instr_hwcnt_dump_complete_type *kbase_instr_hwcnt_dump_complete_sym static kbase_instr_hwcnt_disable_type *kbase_instr_hwcnt_disable_symbol; static kbase_va_free_type *kbase_va_free_symbol; static kbase_destroy_context_type *kbase_destroy_context_symbol; +#endif static long shader_present_low = 0; @@ -99,6 +115,8 @@ enum { MMU_BLOCK }; +static const char mali_name[] = "Mali-T6xx"; + /* Counters for Mali-T6xx: * * - HW counters, 4 blocks @@ -381,6 +399,14 @@ static const char *const hardware_counter_names[] = { #define GET_HW_BLOCK(c) (((c) >> 6) & 0x3) #define GET_COUNTER_OFFSET(c) ((c) & 0x3f) +#if MALI_DDK_GATOR_API_VERSION == 3 +/* Opaque handles for kbase_context and kbase_hwc_dma_mapping */ +static struct mali_dd_hwcnt_handles *handles; + +/* Information about hardware counters */ +static struct mali_dd_hwcnt_info *in_out_info; + +#else /* Memory to dump hardware counters into */ static void *kernel_dump_buffer; @@ -390,14 +416,9 @@ kbase_hwc_dma_mapping kernel_dump_buffer_handle; #endif /* kbase context and device */ -static kbase_context *kbcontext = NULL; +static struct kbase_context *kbcontext = NULL; static struct kbase_device *kbdevice = NULL; - -/* - * The following function has no external prototype in older DDK revisions. When the DDK - * is updated then this should be removed. - */ -struct kbase_device *kbase_find_device(int minor); +#endif static volatile bool kbase_device_busy = false; static unsigned int num_hardware_counters_enabled; @@ -412,6 +433,13 @@ static mali_counter counters[NUMBER_OF_HARDWARE_COUNTERS]; */ static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2]; +extern mali_counter mali_activity[3]; +static const char* const mali_activity_names[] = { + "fragment", + "vertex", + "opencl", +}; + #define SYMBOL_GET(FUNCTION, ERROR_COUNT) \ if(FUNCTION ## _symbol) \ { \ @@ -431,8 +459,8 @@ static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2]; #define SYMBOL_CLEANUP(FUNCTION) \ if(FUNCTION ## _symbol) \ { \ - symbol_put(FUNCTION); \ - FUNCTION ## _symbol = NULL; \ + symbol_put(FUNCTION); \ + FUNCTION ## _symbol = NULL; \ } /** @@ -442,6 +470,12 @@ static unsigned long counter_dump[NUMBER_OF_HARDWARE_COUNTERS * 2]; static int init_symbols(void) { int error_count = 0; +#if MALI_DDK_GATOR_API_VERSION == 3 + SYMBOL_GET(kbase_dd_instr_hwcnt_dump_irq, error_count); + SYMBOL_GET(kbase_dd_instr_hwcnt_dump_complete, error_count); + SYMBOL_GET(mali_dd_hwcnt_init, error_count); + SYMBOL_GET(mali_dd_hwcnt_clear, error_count); +#else SYMBOL_GET(kbase_find_device, error_count); SYMBOL_GET(kbase_create_context, error_count); SYMBOL_GET(kbase_va_alloc, error_count); @@ -452,6 +486,7 @@ static int init_symbols(void) SYMBOL_GET(kbase_instr_hwcnt_disable, error_count); SYMBOL_GET(kbase_va_free, error_count); SYMBOL_GET(kbase_destroy_context, error_count); +#endif return error_count; } @@ -461,6 +496,12 @@ static int init_symbols(void) */ static void clean_symbols(void) { +#if MALI_DDK_GATOR_API_VERSION == 3 + SYMBOL_CLEANUP(kbase_dd_instr_hwcnt_dump_irq); + SYMBOL_CLEANUP(kbase_dd_instr_hwcnt_dump_complete); + SYMBOL_CLEANUP(mali_dd_hwcnt_init); + SYMBOL_CLEANUP(mali_dd_hwcnt_clear); +#else SYMBOL_CLEANUP(kbase_find_device); SYMBOL_CLEANUP(kbase_create_context); SYMBOL_CLEANUP(kbase_va_alloc); @@ -471,6 +512,7 @@ static void clean_symbols(void) SYMBOL_CLEANUP(kbase_instr_hwcnt_disable); SYMBOL_CLEANUP(kbase_va_free); SYMBOL_CLEANUP(kbase_destroy_context); +#endif } /** @@ -502,11 +544,13 @@ static int is_read_scheduled(const struct timespec *current_time, u32 *prev_time static int start(void) { - kbase_uk_hwcnt_setup setup; +#if MALI_DDK_GATOR_API_VERSION < 3 + struct kbase_uk_hwcnt_setup setup; + unsigned long long shadersPresent = 0; + u16 bitmask[] = { 0, 0, 0, 0 }; mali_error err; +#endif int cnt; - u16 bitmask[] = { 0, 0, 0, 0 }; - unsigned long long shadersPresent = 0; /* Setup HW counters */ num_hardware_counters_enabled = 0; @@ -515,18 +559,52 @@ static int start(void) pr_debug("Unexpected number of hardware counters defined: expecting 256, got %d\n", NUMBER_OF_HARDWARE_COUNTERS); } +#if MALI_DDK_GATOR_API_VERSION == 3 + /* Declare and initialise mali_dd_hwcnt_info structure */ + in_out_info = kmalloc(sizeof(struct mali_dd_hwcnt_info), GFP_KERNEL); + for (cnt = 0; cnt < 4; cnt++){ + in_out_info->bitmask[cnt] = 0; + } +#endif /* Calculate enable bitmasks based on counters_enabled array */ for (cnt = 0; cnt < NUMBER_OF_HARDWARE_COUNTERS; cnt++) { const mali_counter *counter = &counters[cnt]; if (counter->enabled) { int block = GET_HW_BLOCK(cnt); int enable_bit = GET_COUNTER_OFFSET(cnt) / 4; +#if MALI_DDK_GATOR_API_VERSION == 3 + in_out_info->bitmask[block] |= (1 << enable_bit); +#else bitmask[block] |= (1 << enable_bit); +#endif pr_debug("gator: Mali-T6xx: hardware counter %s selected [%d]\n", hardware_counter_names[cnt], cnt); num_hardware_counters_enabled++; } } +#if MALI_DDK_GATOR_API_VERSION == 3 + /* Create a kbase context for HW counters */ + if (num_hardware_counters_enabled > 0) { + if (init_symbols() > 0) { + clean_symbols(); + /* No Mali driver code entrypoints found - not a fault. */ + return 0; + } + + handles = mali_dd_hwcnt_init_symbol(in_out_info); + + if(handles == NULL) { + goto out; + } + + /* See if we can get the number of shader cores */ + shader_present_low = (unsigned long)in_out_info->shader_present_bitmap; + + kbase_device_busy = false; + } + + return 0; +#else /* Create a kbase context for HW counters */ if (num_hardware_counters_enabled > 0) { if (init_symbols() > 0) { @@ -606,6 +684,7 @@ free_buffer: destroy_context: kbase_destroy_context_symbol(kbcontext); +#endif out: clean_symbols(); @@ -615,7 +694,11 @@ out: static void stop(void) { unsigned int cnt; - kbase_context *temp_kbcontext; +#if MALI_DDK_GATOR_API_VERSION == 3 + struct mali_dd_hwcnt_handles *temp_hand; +#else + struct kbase_context *temp_kbcontext; +#endif pr_debug("gator: Mali-T6xx: stop\n"); @@ -625,6 +708,20 @@ static void stop(void) } /* Destroy the context for HW counters */ +#if MALI_DDK_GATOR_API_VERSION == 3 + if (num_hardware_counters_enabled > 0 && handles != NULL) { + /* + * Set the global variable to NULL before destroying it, because + * other function will check this before using it. + */ + temp_hand = handles; + handles = NULL; + + mali_dd_hwcnt_clear_symbol(in_out_info, temp_hand); + + kfree(in_out_info); + +#else if (num_hardware_counters_enabled > 0 && kbcontext != NULL) { /* * Set the global variable to NULL before destroying it, because @@ -642,6 +739,7 @@ static void stop(void) #endif kbase_destroy_context_symbol(temp_kbcontext); +#endif pr_debug("gator: Mali-T6xx: hardware counters stopped\n"); @@ -654,7 +752,7 @@ static int read(int **buffer) int cnt; int len = 0; u32 value = 0; - mali_bool success; + uint32_t success; struct timespec current_time; static u32 prev_time_s = 0; @@ -686,12 +784,21 @@ static int read(int **buffer) 0x500 /* VITHAR_MEMORY_SYSTEM, Block 3 */ }; +#if MALI_DDK_GATOR_API_VERSION == 3 + if (!handles) { + return -1; + } + + /* Mali symbols can be called safely since a kbcontext is valid */ + if (kbase_dd_instr_hwcnt_dump_complete_symbol(handles, &success) == MALI_TRUE) { +#else if (!kbcontext) { return -1; } /* Mali symbols can be called safely since a kbcontext is valid */ if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success) == MALI_TRUE) { +#endif kbase_device_busy = false; if (success == MALI_TRUE) { @@ -702,7 +809,11 @@ static int read(int **buffer) const int block = GET_HW_BLOCK(cnt); const int counter_offset = GET_COUNTER_OFFSET(cnt); +#if MALI_DDK_GATOR_API_VERSION == 3 + const char* block_base_address = (char*)in_out_info->kernel_dump_buffer + vithar_blocks[block]; +#else const char* block_base_address = (char*)kernel_dump_buffer + vithar_blocks[block]; +#endif /* If counter belongs to shader block need to take into account all cores */ if (block == SHADER_BLOCK) { @@ -741,7 +852,11 @@ static int read(int **buffer) if (!kbase_device_busy) { kbase_device_busy = true; +#if MALI_DDK_GATOR_API_VERSION == 3 + kbase_dd_instr_hwcnt_dump_irq_symbol(handles); +#else kbase_instr_hwcnt_dump_irq_symbol(kbcontext); +#endif } } @@ -760,7 +875,12 @@ static int create_files(struct super_block *sb, struct dentry *root) * Create the filesystem for all events */ int counter_index = 0; - const char *mali_name = gator_mali_get_mali_name(); + + for (event = 0; event < ARRAY_SIZE(mali_activity); event++) { + if (gator_mali_create_file_system(mali_name, mali_activity_names[event], sb, root, &mali_activity[event], NULL) != 0) { + return -1; + } + } for (event = 0; event < NUMBER_OF_HARDWARE_COUNTERS; event++) { if (gator_mali_create_file_system(mali_name, hardware_counter_names[counter_index], sb, root, &counters[event], NULL) != 0) @@ -786,6 +906,7 @@ int gator_events_mali_t6xx_hw_init(void) test_all_is_read_scheduled(); #endif + gator_mali_initialise_counters(mali_activity, ARRAY_SIZE(mali_activity)); gator_mali_initialise_counters(counters, NUMBER_OF_HARDWARE_COUNTERS); return gator_events_install(&gator_events_mali_t6xx_interface); |