diff options
Diffstat (limited to 'drivers/gator/gator_events_mali_midgard_hw.c')
-rw-r--r-- | drivers/gator/gator_events_mali_midgard_hw.c | 121 |
1 files changed, 56 insertions, 65 deletions
diff --git a/drivers/gator/gator_events_mali_midgard_hw.c b/drivers/gator/gator_events_mali_midgard_hw.c index 7e1eee30026d..db91c42c7d0c 100644 --- a/drivers/gator/gator_events_mali_midgard_hw.c +++ b/drivers/gator/gator_events_mali_midgard_hw.c @@ -433,7 +433,8 @@ static unsigned int num_hardware_counters_enabled; static struct mali_counter *counters; /* An array used to return the data we recorded as key,value pairs */ -static int *counter_dump; +static long long *counter_dump; +static uint64_t last_read_time; extern struct mali_counter mali_activity[3]; @@ -517,31 +518,6 @@ static void clean_symbols(void) #endif } -/** - * Determines whether a read should take place - * @param current_time The current time, obtained from getnstimeofday() - * @param prev_time_s The number of seconds at the previous read attempt. - * @param next_read_time_ns The time (in ns) when the next read should be allowed. - * - * Note that this function has been separated out here to allow it to be tested. - */ -static int is_read_scheduled(const struct timespec *current_time, u32 *prev_time_s, s32 *next_read_time_ns) -{ - /* If the current ns count rolls over a second, roll the next read time too. */ - if (current_time->tv_sec != *prev_time_s) - *next_read_time_ns = *next_read_time_ns - NSEC_PER_SEC; - - /* Abort the read if the next read time has not arrived. */ - if (current_time->tv_nsec < *next_read_time_ns) - return 0; - - /* Set the next read some fixed time after this one, and update the read timestamp. */ - *next_read_time_ns = current_time->tv_nsec + READ_INTERVAL_NSEC; - - *prev_time_s = current_time->tv_sec; - return 1; -} - static int start(void) { #if MALI_DDK_GATOR_API_VERSION != 3 @@ -552,6 +528,8 @@ static int start(void) #endif int cnt; + last_read_time = 0; + #if MALI_DDK_GATOR_API_VERSION == 3 /* Setup HW counters */ num_hardware_counters_enabled = 0; @@ -620,14 +598,14 @@ static int start(void) /* If we already got a context, fail */ if (kbcontext) { - pr_debug("gator: Mali-Midgard: error context already present\n"); + pr_err("gator: Mali-Midgard: error context already present\n"); goto out; } /* kbcontext will only be valid after all the Mali symbols are loaded successfully */ kbcontext = kbase_create_context_symbol(kbdevice); if (!kbcontext) { - pr_debug("gator: Mali-Midgard: error creating kbase context\n"); + pr_err("gator: Mali-Midgard: error creating kbase context\n"); goto out; } @@ -650,7 +628,7 @@ static int start(void) kernel_dump_buffer = kbase_va_alloc_symbol(kbcontext, 4096, &kernel_dump_buffer_handle); #endif if (!kernel_dump_buffer) { - pr_debug("gator: Mali-Midgard: error trying to allocate va\n"); + pr_err("gator: Mali-Midgard: error trying to allocate va\n"); goto destroy_context; } @@ -665,7 +643,7 @@ static int start(void) /* Use kbase API to enable hardware counters and provide dump buffer */ err = kbase_instr_hwcnt_enable_symbol(kbcontext, &setup); if (err != MALI_ERROR_NONE) { - pr_debug("gator: Mali-Midgard: can't setup hardware counters\n"); + pr_err("gator: Mali-Midgard: can't setup hardware counters\n"); goto free_buffer; } pr_debug("gator: Mali-Midgard: hardware counters enabled\n"); @@ -813,68 +791,80 @@ static int read_counter(const int cnt, const int len, const struct mali_counter return 2; } -static int read(int **buffer, bool sched_switch) +static int read(long long **buffer, bool sched_switch) { int cnt; int len = 0; uint32_t success; - struct timespec current_time; - static u32 prev_time_s; - static s32 next_read_time_ns; + uint64_t curr_time; if (!on_primary_core() || sched_switch) return 0; - getnstimeofday(¤t_time); + /* + * Report the HW counters + * Only process hardware counters if at least one of the hardware counters is enabled. + */ + if (num_hardware_counters_enabled <= 0) + return 0; + + curr_time = gator_get_time(); /* * Discard reads unless a respectable time has passed. This * reduces the load on the GPU without sacrificing accuracy on * the Streamline display. */ - if (!is_read_scheduled(¤t_time, &prev_time_s, &next_read_time_ns)) + if (curr_time - last_read_time < READ_INTERVAL_NSEC) return 0; - /* - * Report the HW counters - * Only process hardware counters if at least one of the hardware counters is enabled. - */ - if (num_hardware_counters_enabled > 0) { #if MALI_DDK_GATOR_API_VERSION == 3 - if (!handles) - return -1; + if (!handles) + return -1; - /* Mali symbols can be called safely since a kbcontext is valid */ - if (kbase_gator_instr_hwcnt_dump_complete_symbol(handles, &success)) { + /* Mali symbols can be called safely since a kbcontext is valid */ + if (kbase_gator_instr_hwcnt_dump_complete_symbol(handles, &success)) { #else - if (!kbcontext) - return -1; + 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 symbols can be called safely since a kbcontext is valid */ + if (kbase_instr_hwcnt_dump_complete_symbol(kbcontext, &success)) { #endif - kbase_device_busy = false; + kbase_device_busy = false; + + /* + * If last_read_time is zero, then this result is from a previous + * capture or in error. + */ + if (success && last_read_time > 0) { + /* Backdate these events to when they were requested */ + counter_dump[len++] = 0; + counter_dump[len++] = last_read_time; - if (success) { - /* Cycle through hardware counters and accumulate totals */ - for (cnt = 0; cnt < number_of_hardware_counters; cnt++) { - const struct mali_counter *counter = &counters[cnt]; + /* Cycle through hardware counters and accumulate totals */ + for (cnt = 0; cnt < number_of_hardware_counters; cnt++) { + const struct mali_counter *counter = &counters[cnt]; - if (counter->enabled) - len += read_counter(cnt, len, counter); - } + if (counter->enabled) + len += read_counter(cnt, len, counter); } + + /* Restore the timestamp */ + counter_dump[len++] = 0; + counter_dump[len++] = curr_time; } + } - if (!kbase_device_busy) { - kbase_device_busy = true; + if (!kbase_device_busy) { + kbase_device_busy = true; + last_read_time = curr_time; #if MALI_DDK_GATOR_API_VERSION == 3 - kbase_gator_instr_hwcnt_dump_irq_symbol(handles); + kbase_gator_instr_hwcnt_dump_irq_symbol(handles); #else - kbase_instr_hwcnt_dump_irq_symbol(kbcontext); + kbase_instr_hwcnt_dump_irq_symbol(kbcontext); #endif - } } /* Update the buffer */ @@ -920,7 +910,7 @@ static void shutdown(void) hardware_counter_names = NULL; if (kbase_gator_hwcnt_term_names_symbol != NULL) { kbase_gator_hwcnt_term_names_symbol(); - pr_err("Released symbols\n"); + pr_debug("gator: Released symbols\n"); } SYMBOL_CLEANUP(kbase_gator_hwcnt_term_names); @@ -928,11 +918,12 @@ static void shutdown(void) } static struct gator_interface gator_events_mali_midgard_interface = { + .name = "mali_midgard_hw", .shutdown = shutdown, .create_files = create_files, .start = start, .stop = stop, - .read = read + .read64 = read }; int gator_events_mali_midgard_hw_init(void) @@ -969,7 +960,7 @@ int gator_events_mali_midgard_hw_init(void) #endif counters = kmalloc(sizeof(*counters)*number_of_hardware_counters, GFP_KERNEL); - counter_dump = kmalloc(sizeof(*counter_dump)*number_of_hardware_counters*2, GFP_KERNEL); + counter_dump = kmalloc(sizeof(*counter_dump)*number_of_hardware_counters*2 + 4, GFP_KERNEL); gator_mali_initialise_counters(mali_activity, ARRAY_SIZE(mali_activity)); gator_mali_initialise_counters(counters, number_of_hardware_counters); |