3 * (C) COPYRIGHT 2011-2016 ARM Limited. All rights reserved.
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
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.
18 #include <linux/anon_inodes.h>
19 #include <linux/atomic.h>
20 #include <linux/hrtimer.h>
21 #include <linux/jiffies.h>
22 #include <linux/kthread.h>
23 #include <linux/list.h>
25 #include <linux/poll.h>
26 #include <linux/preempt.h>
27 #include <linux/slab.h>
28 #include <linux/wait.h>
30 #include <mali_kbase.h>
31 #include <mali_kbase_hwaccess_instr.h>
32 #include <mali_kbase_hwcnt_reader.h>
33 #include <mali_kbase_mem_linux.h>
34 #include <mali_kbase_tlstream.h>
36 /*****************************************************************************/
38 /* Hwcnt reader API version */
39 #define HWCNT_READER_API 1
41 /* The number of nanoseconds in a second. */
42 #define NSECS_IN_SEC 1000000000ull /* ns */
44 /* The time resolution of dumping service. */
45 #define DUMPING_RESOLUTION 500000ull /* ns */
47 /* The maximal supported number of dumping buffers. */
48 #define MAX_BUFFER_COUNT 32
50 /* Size and number of hw counters blocks. */
51 #define NR_CNT_BLOCKS_PER_GROUP 8
52 #define NR_CNT_PER_BLOCK 64
53 #define NR_BYTES_PER_CNT 4
54 #define NR_BYTES_PER_HDR 16
55 #define PRFCNT_EN_MASK_OFFSET 0x8
57 /*****************************************************************************/
75 * struct kbase_vinstr_context - vinstr context per device
76 * @lock: protects the entire vinstr context
77 * @kbdev: pointer to kbase device
78 * @kctx: pointer to kbase context
79 * @vmap: vinstr vmap for mapping hwcnt dump buffer
80 * @gpu_va: GPU hwcnt dump buffer address
81 * @cpu_va: the CPU side mapping of the hwcnt dump buffer
82 * @dump_size: size of the dump buffer in bytes
83 * @bitmap: current set of counters monitored, not always in sync
85 * @reprogram: when true, reprogram hwcnt block with the new set of
87 * @state: vinstr state
88 * @state_lock: protects information about vinstr state
89 * @suspend_waitq: notification queue to trigger state re-validation
90 * @suspend_cnt: reference counter of vinstr's suspend state
91 * @suspend_work: worker to execute on entering suspended state
92 * @resume_work: worker to execute on leaving suspended state
93 * @nclients: number of attached clients, pending or otherwise
94 * @waiting_clients: head of list of clients being periodically sampled
95 * @idle_clients: head of list of clients being idle
96 * @suspended_clients: head of list of clients being suspended
97 * @thread: periodic sampling thread
98 * @waitq: notification queue of sampling thread
99 * @request_pending: request for action for sampling thread
101 struct kbase_vinstr_context {
103 struct kbase_device *kbdev;
104 struct kbase_context *kctx;
106 struct kbase_vmap_struct vmap;
113 enum vinstr_state state;
114 struct spinlock state_lock;
115 wait_queue_head_t suspend_waitq;
116 unsigned int suspend_cnt;
117 struct work_struct suspend_work;
118 struct work_struct resume_work;
121 struct list_head waiting_clients;
122 struct list_head idle_clients;
123 struct list_head suspended_clients;
125 struct task_struct *thread;
126 wait_queue_head_t waitq;
127 atomic_t request_pending;
131 * struct kbase_vinstr_client - a vinstr client attached to a vinstr context
132 * @vinstr_ctx: vinstr context client is attached to
133 * @list: node used to attach this client to list in vinstr context
134 * @buffer_count: number of buffers this client is using
135 * @event_mask: events this client reacts to
136 * @dump_size: size of one dump buffer in bytes
137 * @bitmap: bitmap request for JM, TILER, SHADER and MMU counters
138 * @legacy_buffer: userspace hwcnt dump buffer (legacy interface)
139 * @kernel_buffer: kernel hwcnt dump buffer (kernel client interface)
140 * @accum_buffer: temporary accumulation buffer for preserving counters
141 * @dump_time: next time this clients shall request hwcnt dump
142 * @dump_interval: interval between periodic hwcnt dumps
143 * @dump_buffers: kernel hwcnt dump buffers allocated by this client
144 * @dump_buffers_meta: metadata of dump buffers
145 * @meta_idx: index of metadata being accessed by userspace
146 * @read_idx: index of buffer read by userspace
147 * @write_idx: index of buffer being written by dumping service
148 * @waitq: client's notification queue
149 * @pending: when true, client has attached but hwcnt not yet updated
151 struct kbase_vinstr_client {
152 struct kbase_vinstr_context *vinstr_ctx;
153 struct list_head list;
154 unsigned int buffer_count;
158 void __user *legacy_buffer;
164 struct kbase_hwcnt_reader_metadata *dump_buffers_meta;
168 wait_queue_head_t waitq;
173 * struct kbasep_vinstr_wake_up_timer - vinstr service thread wake up timer
174 * @hrtimer: high resolution timer
175 * @vinstr_ctx: vinstr context
177 struct kbasep_vinstr_wake_up_timer {
178 struct hrtimer hrtimer;
179 struct kbase_vinstr_context *vinstr_ctx;
182 /*****************************************************************************/
184 static int kbasep_vinstr_service_task(void *data);
186 static unsigned int kbasep_vinstr_hwcnt_reader_poll(
189 static long kbasep_vinstr_hwcnt_reader_ioctl(
193 static int kbasep_vinstr_hwcnt_reader_mmap(
195 struct vm_area_struct *vma);
196 static int kbasep_vinstr_hwcnt_reader_release(
200 /* The timeline stream file operations structure. */
201 static const struct file_operations vinstr_client_fops = {
202 .poll = kbasep_vinstr_hwcnt_reader_poll,
203 .unlocked_ioctl = kbasep_vinstr_hwcnt_reader_ioctl,
204 .compat_ioctl = kbasep_vinstr_hwcnt_reader_ioctl,
205 .mmap = kbasep_vinstr_hwcnt_reader_mmap,
206 .release = kbasep_vinstr_hwcnt_reader_release,
209 /*****************************************************************************/
211 static int enable_hwcnt(struct kbase_vinstr_context *vinstr_ctx)
213 struct kbase_context *kctx = vinstr_ctx->kctx;
214 struct kbase_device *kbdev = kctx->kbdev;
215 struct kbase_uk_hwcnt_setup setup;
218 setup.dump_buffer = vinstr_ctx->gpu_va;
219 setup.jm_bm = vinstr_ctx->bitmap[JM_HWCNT_BM];
220 setup.tiler_bm = vinstr_ctx->bitmap[TILER_HWCNT_BM];
221 setup.shader_bm = vinstr_ctx->bitmap[SHADER_HWCNT_BM];
222 setup.mmu_l2_bm = vinstr_ctx->bitmap[MMU_L2_HWCNT_BM];
224 /* Mark the context as active so the GPU is kept turned on */
225 /* A suspend won't happen here, because we're in a syscall from a
226 * userspace thread. */
227 kbase_pm_context_active(kbdev);
229 /* Schedule the context in */
230 kbasep_js_schedule_privileged_ctx(kbdev, kctx);
231 err = kbase_instr_hwcnt_enable_internal(kbdev, kctx, &setup);
233 /* Release the context. This had its own Power Manager Active
235 kbasep_js_release_privileged_ctx(kbdev, kctx);
237 /* Also release our Power Manager Active reference */
238 kbase_pm_context_idle(kbdev);
244 static void disable_hwcnt(struct kbase_vinstr_context *vinstr_ctx)
246 struct kbase_context *kctx = vinstr_ctx->kctx;
247 struct kbase_device *kbdev = kctx->kbdev;
250 err = kbase_instr_hwcnt_disable_internal(kctx);
252 dev_warn(kbdev->dev, "Failed to disable HW counters (ctx:%p)",
257 /* Release the context. This had its own Power Manager Active reference. */
258 kbasep_js_release_privileged_ctx(kbdev, kctx);
260 /* Also release our Power Manager Active reference. */
261 kbase_pm_context_idle(kbdev);
263 dev_dbg(kbdev->dev, "HW counters dumping disabled for context %p", kctx);
266 static int reprogram_hwcnt(struct kbase_vinstr_context *vinstr_ctx)
268 disable_hwcnt(vinstr_ctx);
269 return enable_hwcnt(vinstr_ctx);
272 static void hwcnt_bitmap_set(u32 dst[4], u32 src[4])
274 dst[JM_HWCNT_BM] = src[JM_HWCNT_BM];
275 dst[TILER_HWCNT_BM] = src[TILER_HWCNT_BM];
276 dst[SHADER_HWCNT_BM] = src[SHADER_HWCNT_BM];
277 dst[MMU_L2_HWCNT_BM] = src[MMU_L2_HWCNT_BM];
280 static void hwcnt_bitmap_union(u32 dst[4], u32 src[4])
282 dst[JM_HWCNT_BM] |= src[JM_HWCNT_BM];
283 dst[TILER_HWCNT_BM] |= src[TILER_HWCNT_BM];
284 dst[SHADER_HWCNT_BM] |= src[SHADER_HWCNT_BM];
285 dst[MMU_L2_HWCNT_BM] |= src[MMU_L2_HWCNT_BM];
288 size_t kbase_vinstr_dump_size(struct kbase_device *kbdev)
292 #ifndef CONFIG_MALI_NO_MALI
293 if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_V4)) {
296 nr_cg = kbdev->gpu_props.num_core_groups;
297 dump_size = nr_cg * NR_CNT_BLOCKS_PER_GROUP *
301 #endif /* CONFIG_MALI_NO_MALI */
303 /* assume v5 for now */
304 base_gpu_props *props = &kbdev->gpu_props.props;
305 u32 nr_l2 = props->l2_props.num_l2_slices;
306 u64 core_mask = props->coherency_info.group[0].core_mask;
307 u32 nr_blocks = fls64(core_mask);
309 /* JM and tiler counter blocks are always present */
310 dump_size = (2 + nr_l2 + nr_blocks) *
316 KBASE_EXPORT_TEST_API(kbase_vinstr_dump_size);
318 static size_t kbasep_vinstr_dump_size_ctx(
319 struct kbase_vinstr_context *vinstr_ctx)
321 return kbase_vinstr_dump_size(vinstr_ctx->kctx->kbdev);
324 static int kbasep_vinstr_map_kernel_dump_buffer(
325 struct kbase_vinstr_context *vinstr_ctx)
327 struct kbase_va_region *reg;
328 struct kbase_context *kctx = vinstr_ctx->kctx;
332 flags = BASE_MEM_PROT_CPU_RD | BASE_MEM_PROT_GPU_WR;
333 vinstr_ctx->dump_size = kbasep_vinstr_dump_size_ctx(vinstr_ctx);
334 nr_pages = PFN_UP(vinstr_ctx->dump_size);
336 reg = kbase_mem_alloc(kctx, nr_pages, nr_pages, 0, &flags,
337 &vinstr_ctx->gpu_va, &va_align);
341 vinstr_ctx->cpu_va = kbase_vmap(
344 vinstr_ctx->dump_size,
346 if (!vinstr_ctx->cpu_va) {
347 kbase_mem_free(kctx, vinstr_ctx->gpu_va);
354 static void kbasep_vinstr_unmap_kernel_dump_buffer(
355 struct kbase_vinstr_context *vinstr_ctx)
357 struct kbase_context *kctx = vinstr_ctx->kctx;
359 kbase_vunmap(kctx, &vinstr_ctx->vmap);
360 kbase_mem_free(kctx, vinstr_ctx->gpu_va);
364 * kbasep_vinstr_create_kctx - create kernel context for vinstr
365 * @vinstr_ctx: vinstr context
366 * Return: zero on success
368 static int kbasep_vinstr_create_kctx(struct kbase_vinstr_context *vinstr_ctx)
370 struct kbase_device *kbdev = vinstr_ctx->kbdev;
371 struct kbasep_kctx_list_element *element;
373 bool enable_backend = false;
376 vinstr_ctx->kctx = kbase_create_context(vinstr_ctx->kbdev, true);
377 if (!vinstr_ctx->kctx)
380 /* Map the master kernel dump buffer. The HW dumps the counters
381 * into this memory region. */
382 err = kbasep_vinstr_map_kernel_dump_buffer(vinstr_ctx);
384 kbase_destroy_context(vinstr_ctx->kctx);
385 vinstr_ctx->kctx = NULL;
389 /* Add kernel context to list of contexts associated with device. */
390 element = kzalloc(sizeof(*element), GFP_KERNEL);
392 element->kctx = vinstr_ctx->kctx;
393 mutex_lock(&kbdev->kctx_list_lock);
394 list_add(&element->link, &kbdev->kctx_list);
396 /* Inform timeline client about new context.
397 * Do this while holding the lock to avoid tracepoint
398 * being created in both body and summary stream. */
399 kbase_tlstream_tl_new_ctx(
401 (u32)(vinstr_ctx->kctx->id),
402 (u32)(vinstr_ctx->kctx->tgid));
404 mutex_unlock(&kbdev->kctx_list_lock);
406 /* Don't treat this as a fail - just warn about it. */
408 "couldn't add kctx to kctx_list\n");
411 /* Don't enable hardware counters if vinstr is suspended.
412 * Note that vinstr resume code is run under vinstr context lock,
413 * lower layer will be enabled as needed on resume. */
414 spin_lock_irqsave(&vinstr_ctx->state_lock, flags);
415 if (VINSTR_IDLE == vinstr_ctx->state)
416 enable_backend = true;
417 spin_unlock_irqrestore(&vinstr_ctx->state_lock, flags);
419 err = enable_hwcnt(vinstr_ctx);
422 kbasep_vinstr_unmap_kernel_dump_buffer(vinstr_ctx);
423 kbase_destroy_context(vinstr_ctx->kctx);
425 mutex_lock(&kbdev->kctx_list_lock);
426 list_del(&element->link);
428 mutex_unlock(&kbdev->kctx_list_lock);
430 kbase_tlstream_tl_del_ctx(vinstr_ctx->kctx);
431 vinstr_ctx->kctx = NULL;
435 vinstr_ctx->thread = kthread_run(
436 kbasep_vinstr_service_task,
438 "mali_vinstr_service");
439 if (!vinstr_ctx->thread) {
440 disable_hwcnt(vinstr_ctx);
441 kbasep_vinstr_unmap_kernel_dump_buffer(vinstr_ctx);
442 kbase_destroy_context(vinstr_ctx->kctx);
444 mutex_lock(&kbdev->kctx_list_lock);
445 list_del(&element->link);
447 mutex_unlock(&kbdev->kctx_list_lock);
449 kbase_tlstream_tl_del_ctx(vinstr_ctx->kctx);
450 vinstr_ctx->kctx = NULL;
458 * kbasep_vinstr_destroy_kctx - destroy vinstr's kernel context
459 * @vinstr_ctx: vinstr context
461 static void kbasep_vinstr_destroy_kctx(struct kbase_vinstr_context *vinstr_ctx)
463 struct kbase_device *kbdev = vinstr_ctx->kbdev;
464 struct kbasep_kctx_list_element *element;
465 struct kbasep_kctx_list_element *tmp;
468 /* Release hw counters dumping resources. */
469 vinstr_ctx->thread = NULL;
470 disable_hwcnt(vinstr_ctx);
471 kbasep_vinstr_unmap_kernel_dump_buffer(vinstr_ctx);
472 kbase_destroy_context(vinstr_ctx->kctx);
474 /* Remove kernel context from the device's contexts list. */
475 mutex_lock(&kbdev->kctx_list_lock);
476 list_for_each_entry_safe(element, tmp, &kbdev->kctx_list, link) {
477 if (element->kctx == vinstr_ctx->kctx) {
478 list_del(&element->link);
483 mutex_unlock(&kbdev->kctx_list_lock);
486 dev_warn(kbdev->dev, "kctx not in kctx_list\n");
488 /* Inform timeline client about context destruction. */
489 kbase_tlstream_tl_del_ctx(vinstr_ctx->kctx);
491 vinstr_ctx->kctx = NULL;
495 * kbasep_vinstr_attach_client - Attach a client to the vinstr core
496 * @vinstr_ctx: vinstr context
497 * @buffer_count: requested number of dump buffers
498 * @bitmap: bitmaps describing which counters should be enabled
499 * @argp: pointer where notification descriptor shall be stored
500 * @kernel_buffer: pointer to kernel side buffer
502 * Return: vinstr opaque client handle or NULL on failure
504 static struct kbase_vinstr_client *kbasep_vinstr_attach_client(
505 struct kbase_vinstr_context *vinstr_ctx, u32 buffer_count,
506 u32 bitmap[4], void *argp, void *kernel_buffer)
508 struct task_struct *thread = NULL;
509 struct kbase_vinstr_client *cli;
511 KBASE_DEBUG_ASSERT(vinstr_ctx);
513 if (buffer_count > MAX_BUFFER_COUNT
514 || (buffer_count & (buffer_count - 1)))
517 cli = kzalloc(sizeof(*cli), GFP_KERNEL);
521 cli->vinstr_ctx = vinstr_ctx;
522 cli->buffer_count = buffer_count;
524 (1 << BASE_HWCNT_READER_EVENT_MANUAL) |
525 (1 << BASE_HWCNT_READER_EVENT_PERIODIC);
528 hwcnt_bitmap_set(cli->bitmap, bitmap);
530 mutex_lock(&vinstr_ctx->lock);
532 hwcnt_bitmap_union(vinstr_ctx->bitmap, cli->bitmap);
533 vinstr_ctx->reprogram = true;
535 /* If this is the first client, create the vinstr kbase
536 * context. This context is permanently resident until the
537 * last client exits. */
538 if (!vinstr_ctx->nclients) {
539 hwcnt_bitmap_set(vinstr_ctx->bitmap, cli->bitmap);
540 if (kbasep_vinstr_create_kctx(vinstr_ctx) < 0)
543 vinstr_ctx->reprogram = false;
544 cli->pending = false;
547 /* The GPU resets the counter block every time there is a request
548 * to dump it. We need a per client kernel buffer for accumulating
550 cli->dump_size = kbasep_vinstr_dump_size_ctx(vinstr_ctx);
551 cli->accum_buffer = kzalloc(cli->dump_size, GFP_KERNEL);
552 if (!cli->accum_buffer)
555 /* Prepare buffers. */
556 if (cli->buffer_count) {
557 int *fd = (int *)argp;
560 /* Allocate area for buffers metadata storage. */
561 tmp = sizeof(struct kbase_hwcnt_reader_metadata) *
563 cli->dump_buffers_meta = kmalloc(tmp, GFP_KERNEL);
564 if (!cli->dump_buffers_meta)
567 /* Allocate required number of dumping buffers. */
568 cli->dump_buffers = (char *)__get_free_pages(
569 GFP_KERNEL | __GFP_ZERO,
570 get_order(cli->dump_size * cli->buffer_count));
571 if (!cli->dump_buffers)
574 /* Create descriptor for user-kernel data exchange. */
575 *fd = anon_inode_getfd(
576 "[mali_vinstr_desc]",
579 O_RDONLY | O_CLOEXEC);
582 } else if (kernel_buffer) {
583 cli->kernel_buffer = kernel_buffer;
585 cli->legacy_buffer = (void __user *)argp;
588 atomic_set(&cli->read_idx, 0);
589 atomic_set(&cli->meta_idx, 0);
590 atomic_set(&cli->write_idx, 0);
591 init_waitqueue_head(&cli->waitq);
593 vinstr_ctx->nclients++;
594 list_add(&cli->list, &vinstr_ctx->idle_clients);
596 mutex_unlock(&vinstr_ctx->lock);
601 kfree(cli->dump_buffers_meta);
602 if (cli->dump_buffers)
604 (unsigned long)cli->dump_buffers,
605 get_order(cli->dump_size * cli->buffer_count));
606 kfree(cli->accum_buffer);
607 if (!vinstr_ctx->nclients && vinstr_ctx->kctx) {
608 thread = vinstr_ctx->thread;
609 kbasep_vinstr_destroy_kctx(vinstr_ctx);
613 mutex_unlock(&vinstr_ctx->lock);
615 /* Thread must be stopped after lock is released. */
617 kthread_stop(thread);
622 void kbase_vinstr_detach_client(struct kbase_vinstr_client *cli)
624 struct kbase_vinstr_context *vinstr_ctx;
625 struct kbase_vinstr_client *iter, *tmp;
626 struct task_struct *thread = NULL;
627 u32 zerobitmap[4] = { 0 };
630 KBASE_DEBUG_ASSERT(cli);
631 vinstr_ctx = cli->vinstr_ctx;
632 KBASE_DEBUG_ASSERT(vinstr_ctx);
634 mutex_lock(&vinstr_ctx->lock);
636 list_for_each_entry_safe(iter, tmp, &vinstr_ctx->idle_clients, list) {
638 vinstr_ctx->reprogram = true;
640 list_del(&iter->list);
645 list_for_each_entry_safe(
646 iter, tmp, &vinstr_ctx->waiting_clients, list) {
648 vinstr_ctx->reprogram = true;
650 list_del(&iter->list);
655 KBASE_DEBUG_ASSERT(cli_found);
657 kfree(cli->dump_buffers_meta);
659 (unsigned long)cli->dump_buffers,
660 get_order(cli->dump_size * cli->buffer_count));
661 kfree(cli->accum_buffer);
664 vinstr_ctx->nclients--;
665 if (!vinstr_ctx->nclients) {
666 thread = vinstr_ctx->thread;
667 kbasep_vinstr_destroy_kctx(vinstr_ctx);
670 /* Rebuild context bitmap now that the client has detached */
671 hwcnt_bitmap_set(vinstr_ctx->bitmap, zerobitmap);
672 list_for_each_entry(iter, &vinstr_ctx->idle_clients, list)
673 hwcnt_bitmap_union(vinstr_ctx->bitmap, iter->bitmap);
674 list_for_each_entry(iter, &vinstr_ctx->waiting_clients, list)
675 hwcnt_bitmap_union(vinstr_ctx->bitmap, iter->bitmap);
677 mutex_unlock(&vinstr_ctx->lock);
679 /* Thread must be stopped after lock is released. */
681 kthread_stop(thread);
683 KBASE_EXPORT_TEST_API(kbase_vinstr_detach_client);
685 /* Accumulate counters in the dump buffer */
686 static void accum_dump_buffer(void *dst, void *src, size_t dump_size)
688 size_t block_size = NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT;
693 for (i = 0; i < dump_size; i += block_size) {
694 /* skip over the header block */
695 d += NR_BYTES_PER_HDR / sizeof(u32);
696 s += NR_BYTES_PER_HDR / sizeof(u32);
697 for (j = 0; j < (block_size - NR_BYTES_PER_HDR) / sizeof(u32); j++) {
698 /* saturate result if addition would result in wraparound */
699 if (U32_MAX - *d < *s)
709 /* This is the Midgard v4 patch function. It copies the headers for each
710 * of the defined blocks from the master kernel buffer and then patches up
711 * the performance counter enable mask for each of the blocks to exclude
712 * counters that were not requested by the client. */
713 static void patch_dump_buffer_hdr_v4(
714 struct kbase_vinstr_context *vinstr_ctx,
715 struct kbase_vinstr_client *cli)
718 u8 *dst = cli->accum_buffer;
719 u8 *src = vinstr_ctx->cpu_va;
720 u32 nr_cg = vinstr_ctx->kctx->kbdev->gpu_props.num_core_groups;
721 size_t i, group_size, group;
723 SC0_BASE = 0 * NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT,
724 SC1_BASE = 1 * NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT,
725 SC2_BASE = 2 * NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT,
726 SC3_BASE = 3 * NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT,
727 TILER_BASE = 4 * NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT,
728 MMU_L2_BASE = 5 * NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT,
729 JM_BASE = 7 * NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT
732 group_size = NR_CNT_BLOCKS_PER_GROUP *
735 for (i = 0; i < nr_cg; i++) {
736 group = i * group_size;
737 /* copy shader core headers */
738 memcpy(&dst[group + SC0_BASE], &src[group + SC0_BASE],
740 memcpy(&dst[group + SC1_BASE], &src[group + SC1_BASE],
742 memcpy(&dst[group + SC2_BASE], &src[group + SC2_BASE],
744 memcpy(&dst[group + SC3_BASE], &src[group + SC3_BASE],
747 /* copy tiler header */
748 memcpy(&dst[group + TILER_BASE], &src[group + TILER_BASE],
751 /* copy mmu header */
752 memcpy(&dst[group + MMU_L2_BASE], &src[group + MMU_L2_BASE],
755 /* copy job manager header */
756 memcpy(&dst[group + JM_BASE], &src[group + JM_BASE],
759 /* patch the shader core enable mask */
760 mask = (u32 *)&dst[group + SC0_BASE + PRFCNT_EN_MASK_OFFSET];
761 *mask &= cli->bitmap[SHADER_HWCNT_BM];
762 mask = (u32 *)&dst[group + SC1_BASE + PRFCNT_EN_MASK_OFFSET];
763 *mask &= cli->bitmap[SHADER_HWCNT_BM];
764 mask = (u32 *)&dst[group + SC2_BASE + PRFCNT_EN_MASK_OFFSET];
765 *mask &= cli->bitmap[SHADER_HWCNT_BM];
766 mask = (u32 *)&dst[group + SC3_BASE + PRFCNT_EN_MASK_OFFSET];
767 *mask &= cli->bitmap[SHADER_HWCNT_BM];
769 /* patch the tiler core enable mask */
770 mask = (u32 *)&dst[group + TILER_BASE + PRFCNT_EN_MASK_OFFSET];
771 *mask &= cli->bitmap[TILER_HWCNT_BM];
773 /* patch the mmu core enable mask */
774 mask = (u32 *)&dst[group + MMU_L2_BASE + PRFCNT_EN_MASK_OFFSET];
775 *mask &= cli->bitmap[MMU_L2_HWCNT_BM];
777 /* patch the job manager enable mask */
778 mask = (u32 *)&dst[group + JM_BASE + PRFCNT_EN_MASK_OFFSET];
779 *mask &= cli->bitmap[JM_HWCNT_BM];
783 /* This is the Midgard v5 patch function. It copies the headers for each
784 * of the defined blocks from the master kernel buffer and then patches up
785 * the performance counter enable mask for each of the blocks to exclude
786 * counters that were not requested by the client. */
787 static void patch_dump_buffer_hdr_v5(
788 struct kbase_vinstr_context *vinstr_ctx,
789 struct kbase_vinstr_client *cli)
791 struct kbase_device *kbdev = vinstr_ctx->kctx->kbdev;
795 u8 *dst = cli->accum_buffer;
796 u8 *src = vinstr_ctx->cpu_va;
797 size_t block_size = NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT;
799 /* copy and patch job manager header */
800 memcpy(dst, src, NR_BYTES_PER_HDR);
801 mask = (u32 *)&dst[PRFCNT_EN_MASK_OFFSET];
802 *mask &= cli->bitmap[JM_HWCNT_BM];
806 /* copy and patch tiler header */
807 memcpy(dst, src, NR_BYTES_PER_HDR);
808 mask = (u32 *)&dst[PRFCNT_EN_MASK_OFFSET];
809 *mask &= cli->bitmap[TILER_HWCNT_BM];
813 /* copy and patch MMU/L2C headers */
814 nr_l2 = kbdev->gpu_props.props.l2_props.num_l2_slices;
815 for (i = 0; i < nr_l2; i++) {
816 memcpy(dst, src, NR_BYTES_PER_HDR);
817 mask = (u32 *)&dst[PRFCNT_EN_MASK_OFFSET];
818 *mask &= cli->bitmap[MMU_L2_HWCNT_BM];
823 /* copy and patch shader core headers */
824 core_mask = kbdev->gpu_props.props.coherency_info.group[0].core_mask;
825 while (0ull != core_mask) {
826 memcpy(dst, src, NR_BYTES_PER_HDR);
827 if (0ull != (core_mask & 1ull)) {
828 /* if block is not reserved update header */
829 mask = (u32 *)&dst[PRFCNT_EN_MASK_OFFSET];
830 *mask &= cli->bitmap[SHADER_HWCNT_BM];
840 * accum_clients - accumulate dumped hw counters for all known clients
841 * @vinstr_ctx: vinstr context
843 static void accum_clients(struct kbase_vinstr_context *vinstr_ctx)
845 struct kbase_vinstr_client *iter;
848 #ifndef CONFIG_MALI_NO_MALI
849 v4 = kbase_hw_has_feature(vinstr_ctx->kbdev, BASE_HW_FEATURE_V4);
852 list_for_each_entry(iter, &vinstr_ctx->idle_clients, list) {
853 /* Don't bother accumulating clients whose hwcnt requests
854 * have not yet been honoured. */
858 patch_dump_buffer_hdr_v4(vinstr_ctx, iter);
860 patch_dump_buffer_hdr_v5(vinstr_ctx, iter);
866 list_for_each_entry(iter, &vinstr_ctx->waiting_clients, list) {
867 /* Don't bother accumulating clients whose hwcnt requests
868 * have not yet been honoured. */
872 patch_dump_buffer_hdr_v4(vinstr_ctx, iter);
874 patch_dump_buffer_hdr_v5(vinstr_ctx, iter);
882 /*****************************************************************************/
885 * kbasep_vinstr_get_timestamp - return timestamp
887 * Function returns timestamp value based on raw monotonic timer. Value will
888 * wrap around zero in case of overflow.
890 * Return: timestamp value
892 static u64 kbasep_vinstr_get_timestamp(void)
896 getrawmonotonic(&ts);
897 return (u64)ts.tv_sec * NSECS_IN_SEC + ts.tv_nsec;
901 * kbasep_vinstr_add_dump_request - register client's dumping request
902 * @cli: requesting client
903 * @waiting_clients: list of pending dumping requests
905 static void kbasep_vinstr_add_dump_request(
906 struct kbase_vinstr_client *cli,
907 struct list_head *waiting_clients)
909 struct kbase_vinstr_client *tmp;
911 if (list_empty(waiting_clients)) {
912 list_add(&cli->list, waiting_clients);
915 list_for_each_entry(tmp, waiting_clients, list) {
916 if (tmp->dump_time > cli->dump_time) {
917 list_add_tail(&cli->list, &tmp->list);
921 list_add_tail(&cli->list, waiting_clients);
925 * kbasep_vinstr_collect_and_accumulate - collect hw counters via low level
926 * dump and accumulate them for known
928 * @vinstr_ctx: vinstr context
929 * @timestamp: pointer where collection timestamp will be recorded
931 * Return: zero on success
933 static int kbasep_vinstr_collect_and_accumulate(
934 struct kbase_vinstr_context *vinstr_ctx, u64 *timestamp)
939 #ifdef CONFIG_MALI_NO_MALI
940 /* The dummy model needs the CPU mapping. */
941 gpu_model_set_dummy_prfcnt_base_cpu(vinstr_ctx->cpu_va);
944 spin_lock_irqsave(&vinstr_ctx->state_lock, flags);
945 if (VINSTR_IDLE != vinstr_ctx->state) {
946 spin_unlock_irqrestore(&vinstr_ctx->state_lock, flags);
949 vinstr_ctx->state = VINSTR_DUMPING;
951 spin_unlock_irqrestore(&vinstr_ctx->state_lock, flags);
953 /* Request HW counters dump.
954 * Disable preemption to make dump timestamp more accurate. */
956 *timestamp = kbasep_vinstr_get_timestamp();
957 rcode = kbase_instr_hwcnt_request_dump(vinstr_ctx->kctx);
961 rcode = kbase_instr_hwcnt_wait_for_dump(vinstr_ctx->kctx);
964 spin_lock_irqsave(&vinstr_ctx->state_lock, flags);
965 switch (vinstr_ctx->state)
967 case VINSTR_SUSPENDING:
968 schedule_work(&vinstr_ctx->suspend_work);
971 vinstr_ctx->state = VINSTR_IDLE;
972 wake_up_all(&vinstr_ctx->suspend_waitq);
977 spin_unlock_irqrestore(&vinstr_ctx->state_lock, flags);
979 /* Accumulate values of collected counters. */
981 accum_clients(vinstr_ctx);
987 * kbasep_vinstr_fill_dump_buffer - copy accumulated counters to empty kernel
989 * @cli: requesting client
990 * @timestamp: timestamp when counters were collected
991 * @event_id: id of event that caused triggered counters collection
993 * Return: zero on success
995 static int kbasep_vinstr_fill_dump_buffer(
996 struct kbase_vinstr_client *cli, u64 timestamp,
997 enum base_hwcnt_reader_event event_id)
999 unsigned int write_idx = atomic_read(&cli->write_idx);
1000 unsigned int read_idx = atomic_read(&cli->read_idx);
1002 struct kbase_hwcnt_reader_metadata *meta;
1005 /* Check if there is a place to copy HWC block into. */
1006 if (write_idx - read_idx == cli->buffer_count)
1008 write_idx %= cli->buffer_count;
1010 /* Fill in dump buffer and its metadata. */
1011 buffer = &cli->dump_buffers[write_idx * cli->dump_size];
1012 meta = &cli->dump_buffers_meta[write_idx];
1013 meta->timestamp = timestamp;
1014 meta->event_id = event_id;
1015 meta->buffer_idx = write_idx;
1016 memcpy(buffer, cli->accum_buffer, cli->dump_size);
1021 * kbasep_vinstr_fill_dump_buffer_legacy - copy accumulated counters to buffer
1022 * allocated in userspace
1023 * @cli: requesting client
1025 * Return: zero on success
1027 * This is part of legacy ioctl interface.
1029 static int kbasep_vinstr_fill_dump_buffer_legacy(
1030 struct kbase_vinstr_client *cli)
1032 void __user *buffer = cli->legacy_buffer;
1035 /* Copy data to user buffer. */
1036 rcode = copy_to_user(buffer, cli->accum_buffer, cli->dump_size);
1038 pr_warn("error while copying buffer to user\n");
1043 * kbasep_vinstr_fill_dump_buffer_kernel - copy accumulated counters to buffer
1044 * allocated in kernel space
1045 * @cli: requesting client
1047 * Return: zero on success
1049 * This is part of the kernel client interface.
1051 static int kbasep_vinstr_fill_dump_buffer_kernel(
1052 struct kbase_vinstr_client *cli)
1054 memcpy(cli->kernel_buffer, cli->accum_buffer, cli->dump_size);
1060 * kbasep_vinstr_reprogram - reprogram hwcnt set collected by inst
1061 * @vinstr_ctx: vinstr context
1063 static void kbasep_vinstr_reprogram(
1064 struct kbase_vinstr_context *vinstr_ctx)
1066 unsigned long flags;
1067 bool suspended = false;
1069 /* Don't enable hardware counters if vinstr is suspended. */
1070 spin_lock_irqsave(&vinstr_ctx->state_lock, flags);
1071 if (VINSTR_IDLE != vinstr_ctx->state)
1073 spin_unlock_irqrestore(&vinstr_ctx->state_lock, flags);
1077 /* Change to suspended state is done while holding vinstr context
1078 * lock. Below code will then no re-enable the instrumentation. */
1080 if (vinstr_ctx->reprogram) {
1081 struct kbase_vinstr_client *iter;
1083 if (!reprogram_hwcnt(vinstr_ctx)) {
1084 vinstr_ctx->reprogram = false;
1085 list_for_each_entry(
1087 &vinstr_ctx->idle_clients,
1089 iter->pending = false;
1090 list_for_each_entry(
1092 &vinstr_ctx->waiting_clients,
1094 iter->pending = false;
1100 * kbasep_vinstr_update_client - copy accumulated counters to user readable
1101 * buffer and notify the user
1102 * @cli: requesting client
1103 * @timestamp: timestamp when counters were collected
1104 * @event_id: id of event that caused triggered counters collection
1106 * Return: zero on success
1108 static int kbasep_vinstr_update_client(
1109 struct kbase_vinstr_client *cli, u64 timestamp,
1110 enum base_hwcnt_reader_event event_id)
1114 /* Copy collected counters to user readable buffer. */
1115 if (cli->buffer_count)
1116 rcode = kbasep_vinstr_fill_dump_buffer(
1117 cli, timestamp, event_id);
1118 else if (cli->kernel_buffer)
1119 rcode = kbasep_vinstr_fill_dump_buffer_kernel(cli);
1121 rcode = kbasep_vinstr_fill_dump_buffer_legacy(cli);
1127 /* Notify client. Make sure all changes to memory are visible. */
1129 atomic_inc(&cli->write_idx);
1130 wake_up_interruptible(&cli->waitq);
1132 /* Prepare for next request. */
1133 memset(cli->accum_buffer, 0, cli->dump_size);
1140 * kbasep_vinstr_wake_up_callback - vinstr wake up timer wake up function
1142 * @hrtimer: high resolution timer
1144 * Return: High resolution timer restart enum.
1146 static enum hrtimer_restart kbasep_vinstr_wake_up_callback(
1147 struct hrtimer *hrtimer)
1149 struct kbasep_vinstr_wake_up_timer *timer =
1152 struct kbasep_vinstr_wake_up_timer,
1155 KBASE_DEBUG_ASSERT(timer);
1157 atomic_set(&timer->vinstr_ctx->request_pending, 1);
1158 wake_up_all(&timer->vinstr_ctx->waitq);
1160 return HRTIMER_NORESTART;
1164 * kbasep_vinstr_service_task - HWC dumping service thread
1166 * @data: Pointer to vinstr context structure.
1168 * Return: Always returns zero.
1170 static int kbasep_vinstr_service_task(void *data)
1172 struct kbase_vinstr_context *vinstr_ctx = data;
1173 struct kbasep_vinstr_wake_up_timer timer;
1175 KBASE_DEBUG_ASSERT(vinstr_ctx);
1177 hrtimer_init(&timer.hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
1178 timer.hrtimer.function = kbasep_vinstr_wake_up_callback;
1179 timer.vinstr_ctx = vinstr_ctx;
1181 while (!kthread_should_stop()) {
1182 struct kbase_vinstr_client *cli = NULL;
1183 struct kbase_vinstr_client *tmp;
1186 u64 timestamp = kbasep_vinstr_get_timestamp();
1188 struct list_head expired_requests;
1190 /* Hold lock while performing operations on lists of clients. */
1191 mutex_lock(&vinstr_ctx->lock);
1193 /* Closing thread must not interact with client requests. */
1194 if (current == vinstr_ctx->thread) {
1195 atomic_set(&vinstr_ctx->request_pending, 0);
1197 if (!list_empty(&vinstr_ctx->waiting_clients)) {
1198 cli = list_first_entry(
1199 &vinstr_ctx->waiting_clients,
1200 struct kbase_vinstr_client,
1202 dump_time = cli->dump_time;
1206 if (!cli || ((s64)timestamp - (s64)dump_time < 0ll)) {
1207 mutex_unlock(&vinstr_ctx->lock);
1209 /* Sleep until next dumping event or service request. */
1211 u64 diff = dump_time - timestamp;
1221 &vinstr_ctx->request_pending) ||
1222 kthread_should_stop());
1223 hrtimer_cancel(&timer.hrtimer);
1227 rcode = kbasep_vinstr_collect_and_accumulate(vinstr_ctx,
1230 INIT_LIST_HEAD(&expired_requests);
1232 /* Find all expired requests. */
1233 list_for_each_entry_safe(
1236 &vinstr_ctx->waiting_clients,
1239 (s64)(timestamp + DUMPING_RESOLUTION) -
1240 (s64)cli->dump_time;
1242 list_del(&cli->list);
1243 list_add(&cli->list, &expired_requests);
1249 /* Fill data for each request found. */
1250 list_for_each_entry_safe(cli, tmp, &expired_requests, list) {
1251 /* Ensure that legacy buffer will not be used from
1252 * this kthread context. */
1253 BUG_ON(0 == cli->buffer_count);
1254 /* Expect only periodically sampled clients. */
1255 BUG_ON(0 == cli->dump_interval);
1258 kbasep_vinstr_update_client(
1261 BASE_HWCNT_READER_EVENT_PERIODIC);
1263 /* Set new dumping time. Drop missed probing times. */
1265 cli->dump_time += cli->dump_interval;
1266 } while (cli->dump_time < timestamp);
1268 list_del(&cli->list);
1269 kbasep_vinstr_add_dump_request(
1271 &vinstr_ctx->waiting_clients);
1274 /* Reprogram counters set if required. */
1275 kbasep_vinstr_reprogram(vinstr_ctx);
1277 mutex_unlock(&vinstr_ctx->lock);
1283 /*****************************************************************************/
1286 * kbasep_vinstr_hwcnt_reader_buffer_ready - check if client has ready buffers
1287 * @cli: pointer to vinstr client structure
1289 * Return: non-zero if client has at least one dumping buffer filled that was
1290 * not notified to user yet
1292 static int kbasep_vinstr_hwcnt_reader_buffer_ready(
1293 struct kbase_vinstr_client *cli)
1295 KBASE_DEBUG_ASSERT(cli);
1296 return atomic_read(&cli->write_idx) != atomic_read(&cli->meta_idx);
1300 * kbasep_vinstr_hwcnt_reader_ioctl_get_buffer - hwcnt reader's ioctl command
1301 * @cli: pointer to vinstr client structure
1302 * @buffer: pointer to userspace buffer
1303 * @size: size of buffer
1305 * Return: zero on success
1307 static long kbasep_vinstr_hwcnt_reader_ioctl_get_buffer(
1308 struct kbase_vinstr_client *cli, void __user *buffer,
1311 unsigned int meta_idx = atomic_read(&cli->meta_idx);
1312 unsigned int idx = meta_idx % cli->buffer_count;
1314 struct kbase_hwcnt_reader_metadata *meta = &cli->dump_buffers_meta[idx];
1316 /* Metadata sanity check. */
1317 KBASE_DEBUG_ASSERT(idx == meta->buffer_idx);
1319 if (sizeof(struct kbase_hwcnt_reader_metadata) != size)
1322 /* Check if there is any buffer available. */
1323 if (atomic_read(&cli->write_idx) == meta_idx)
1326 /* Check if previously taken buffer was put back. */
1327 if (atomic_read(&cli->read_idx) != meta_idx)
1330 /* Copy next available buffer's metadata to user. */
1331 if (copy_to_user(buffer, meta, size))
1334 atomic_inc(&cli->meta_idx);
1340 * kbasep_vinstr_hwcnt_reader_ioctl_put_buffer - hwcnt reader's ioctl command
1341 * @cli: pointer to vinstr client structure
1342 * @buffer: pointer to userspace buffer
1343 * @size: size of buffer
1345 * Return: zero on success
1347 static long kbasep_vinstr_hwcnt_reader_ioctl_put_buffer(
1348 struct kbase_vinstr_client *cli, void __user *buffer,
1351 unsigned int read_idx = atomic_read(&cli->read_idx);
1352 unsigned int idx = read_idx % cli->buffer_count;
1354 struct kbase_hwcnt_reader_metadata meta;
1356 if (sizeof(struct kbase_hwcnt_reader_metadata) != size)
1359 /* Check if any buffer was taken. */
1360 if (atomic_read(&cli->meta_idx) == read_idx)
1363 /* Check if correct buffer is put back. */
1364 if (copy_from_user(&meta, buffer, size))
1366 if (idx != meta.buffer_idx)
1369 atomic_inc(&cli->read_idx);
1375 * kbasep_vinstr_hwcnt_reader_ioctl_set_interval - hwcnt reader's ioctl command
1376 * @cli: pointer to vinstr client structure
1377 * @interval: periodic dumping interval (disable periodic dumping if zero)
1379 * Return: zero on success
1381 static long kbasep_vinstr_hwcnt_reader_ioctl_set_interval(
1382 struct kbase_vinstr_client *cli, u32 interval)
1384 struct kbase_vinstr_context *vinstr_ctx = cli->vinstr_ctx;
1386 KBASE_DEBUG_ASSERT(vinstr_ctx);
1388 mutex_lock(&vinstr_ctx->lock);
1390 list_del(&cli->list);
1392 cli->dump_interval = interval;
1394 /* If interval is non-zero, enable periodic dumping for this client. */
1395 if (cli->dump_interval) {
1396 if (DUMPING_RESOLUTION > cli->dump_interval)
1397 cli->dump_interval = DUMPING_RESOLUTION;
1399 kbasep_vinstr_get_timestamp() + cli->dump_interval;
1401 kbasep_vinstr_add_dump_request(
1402 cli, &vinstr_ctx->waiting_clients);
1404 atomic_set(&vinstr_ctx->request_pending, 1);
1405 wake_up_all(&vinstr_ctx->waitq);
1407 list_add(&cli->list, &vinstr_ctx->idle_clients);
1410 mutex_unlock(&vinstr_ctx->lock);
1416 * kbasep_vinstr_hwcnt_reader_event_mask - return event mask for event id
1417 * @event_id: id of event
1418 * Return: event_mask or zero if event is not supported or maskable
1420 static u32 kbasep_vinstr_hwcnt_reader_event_mask(
1421 enum base_hwcnt_reader_event event_id)
1426 case BASE_HWCNT_READER_EVENT_PREJOB:
1427 case BASE_HWCNT_READER_EVENT_POSTJOB:
1428 /* These event are maskable. */
1429 event_mask = (1 << event_id);
1432 case BASE_HWCNT_READER_EVENT_MANUAL:
1433 case BASE_HWCNT_READER_EVENT_PERIODIC:
1434 /* These event are non-maskable. */
1436 /* These event are not supported. */
1444 * kbasep_vinstr_hwcnt_reader_ioctl_enable_event - hwcnt reader's ioctl command
1445 * @cli: pointer to vinstr client structure
1446 * @event_id: id of event to enable
1448 * Return: zero on success
1450 static long kbasep_vinstr_hwcnt_reader_ioctl_enable_event(
1451 struct kbase_vinstr_client *cli,
1452 enum base_hwcnt_reader_event event_id)
1454 struct kbase_vinstr_context *vinstr_ctx = cli->vinstr_ctx;
1457 KBASE_DEBUG_ASSERT(vinstr_ctx);
1459 event_mask = kbasep_vinstr_hwcnt_reader_event_mask(event_id);
1463 mutex_lock(&vinstr_ctx->lock);
1464 cli->event_mask |= event_mask;
1465 mutex_unlock(&vinstr_ctx->lock);
1471 * kbasep_vinstr_hwcnt_reader_ioctl_disable_event - hwcnt reader's ioctl command
1472 * @cli: pointer to vinstr client structure
1473 * @event_id: id of event to disable
1475 * Return: zero on success
1477 static long kbasep_vinstr_hwcnt_reader_ioctl_disable_event(
1478 struct kbase_vinstr_client *cli,
1479 enum base_hwcnt_reader_event event_id)
1481 struct kbase_vinstr_context *vinstr_ctx = cli->vinstr_ctx;
1484 KBASE_DEBUG_ASSERT(vinstr_ctx);
1486 event_mask = kbasep_vinstr_hwcnt_reader_event_mask(event_id);
1490 mutex_lock(&vinstr_ctx->lock);
1491 cli->event_mask &= ~event_mask;
1492 mutex_unlock(&vinstr_ctx->lock);
1498 * kbasep_vinstr_hwcnt_reader_ioctl_get_hwver - hwcnt reader's ioctl command
1499 * @cli: pointer to vinstr client structure
1500 * @hwver: pointer to user buffer where hw version will be stored
1502 * Return: zero on success
1504 static long kbasep_vinstr_hwcnt_reader_ioctl_get_hwver(
1505 struct kbase_vinstr_client *cli, u32 __user *hwver)
1507 #ifndef CONFIG_MALI_NO_MALI
1508 struct kbase_vinstr_context *vinstr_ctx = cli->vinstr_ctx;
1513 #ifndef CONFIG_MALI_NO_MALI
1514 KBASE_DEBUG_ASSERT(vinstr_ctx);
1515 if (kbase_hw_has_feature(vinstr_ctx->kbdev, BASE_HW_FEATURE_V4))
1519 return put_user(ver, hwver);
1523 * kbasep_vinstr_hwcnt_reader_ioctl - hwcnt reader's ioctl
1524 * @filp: pointer to file structure
1525 * @cmd: user command
1526 * @arg: command's argument
1528 * Return: zero on success
1530 static long kbasep_vinstr_hwcnt_reader_ioctl(struct file *filp,
1531 unsigned int cmd, unsigned long arg)
1534 struct kbase_vinstr_client *cli;
1536 KBASE_DEBUG_ASSERT(filp);
1538 cli = filp->private_data;
1539 KBASE_DEBUG_ASSERT(cli);
1541 if (unlikely(KBASE_HWCNT_READER != _IOC_TYPE(cmd)))
1545 case KBASE_HWCNT_READER_GET_API_VERSION:
1546 rcode = put_user(HWCNT_READER_API, (u32 __user *)arg);
1548 case KBASE_HWCNT_READER_GET_HWVER:
1549 rcode = kbasep_vinstr_hwcnt_reader_ioctl_get_hwver(
1550 cli, (u32 __user *)arg);
1552 case KBASE_HWCNT_READER_GET_BUFFER_SIZE:
1553 KBASE_DEBUG_ASSERT(cli->vinstr_ctx);
1555 (u32)cli->vinstr_ctx->dump_size,
1558 case KBASE_HWCNT_READER_DUMP:
1559 rcode = kbase_vinstr_hwc_dump(
1560 cli, BASE_HWCNT_READER_EVENT_MANUAL);
1562 case KBASE_HWCNT_READER_CLEAR:
1563 rcode = kbase_vinstr_hwc_clear(cli);
1565 case KBASE_HWCNT_READER_GET_BUFFER:
1566 rcode = kbasep_vinstr_hwcnt_reader_ioctl_get_buffer(
1567 cli, (void __user *)arg, _IOC_SIZE(cmd));
1569 case KBASE_HWCNT_READER_PUT_BUFFER:
1570 rcode = kbasep_vinstr_hwcnt_reader_ioctl_put_buffer(
1571 cli, (void __user *)arg, _IOC_SIZE(cmd));
1573 case KBASE_HWCNT_READER_SET_INTERVAL:
1574 rcode = kbasep_vinstr_hwcnt_reader_ioctl_set_interval(
1577 case KBASE_HWCNT_READER_ENABLE_EVENT:
1578 rcode = kbasep_vinstr_hwcnt_reader_ioctl_enable_event(
1579 cli, (enum base_hwcnt_reader_event)arg);
1581 case KBASE_HWCNT_READER_DISABLE_EVENT:
1582 rcode = kbasep_vinstr_hwcnt_reader_ioctl_disable_event(
1583 cli, (enum base_hwcnt_reader_event)arg);
1594 * kbasep_vinstr_hwcnt_reader_poll - hwcnt reader's poll
1595 * @filp: pointer to file structure
1596 * @wait: pointer to poll table
1597 * Return: POLLIN if data can be read without blocking, otherwise zero
1599 static unsigned int kbasep_vinstr_hwcnt_reader_poll(struct file *filp,
1602 struct kbase_vinstr_client *cli;
1604 KBASE_DEBUG_ASSERT(filp);
1605 KBASE_DEBUG_ASSERT(wait);
1607 cli = filp->private_data;
1608 KBASE_DEBUG_ASSERT(cli);
1610 poll_wait(filp, &cli->waitq, wait);
1611 if (kbasep_vinstr_hwcnt_reader_buffer_ready(cli))
1617 * kbasep_vinstr_hwcnt_reader_mmap - hwcnt reader's mmap
1618 * @filp: pointer to file structure
1619 * @vma: pointer to vma structure
1620 * Return: zero on success
1622 static int kbasep_vinstr_hwcnt_reader_mmap(struct file *filp,
1623 struct vm_area_struct *vma)
1625 struct kbase_vinstr_client *cli;
1626 unsigned long size, addr, pfn, offset;
1627 unsigned long vm_size = vma->vm_end - vma->vm_start;
1629 KBASE_DEBUG_ASSERT(filp);
1630 KBASE_DEBUG_ASSERT(vma);
1632 cli = filp->private_data;
1633 KBASE_DEBUG_ASSERT(cli);
1635 size = cli->buffer_count * cli->dump_size;
1637 if (vma->vm_pgoff > (size >> PAGE_SHIFT))
1642 offset = vma->vm_pgoff << PAGE_SHIFT;
1643 if ((vm_size + offset) > size)
1646 addr = __pa((unsigned long)cli->dump_buffers + offset);
1647 pfn = addr >> PAGE_SHIFT;
1649 return remap_pfn_range(
1658 * kbasep_vinstr_hwcnt_reader_release - hwcnt reader's release
1659 * @inode: pointer to inode structure
1660 * @filp: pointer to file structure
1661 * Return always return zero
1663 static int kbasep_vinstr_hwcnt_reader_release(struct inode *inode,
1666 struct kbase_vinstr_client *cli;
1668 KBASE_DEBUG_ASSERT(inode);
1669 KBASE_DEBUG_ASSERT(filp);
1671 cli = filp->private_data;
1672 KBASE_DEBUG_ASSERT(cli);
1674 kbase_vinstr_detach_client(cli);
1678 /*****************************************************************************/
1681 * kbasep_vinstr_kick_scheduler - trigger scheduler cycle
1682 * @kbdev: pointer to kbase device structure
1684 static void kbasep_vinstr_kick_scheduler(struct kbase_device *kbdev)
1686 struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
1687 unsigned long flags;
1689 down(&js_devdata->schedule_sem);
1690 spin_lock_irqsave(&js_devdata->runpool_irq.lock, flags);
1691 kbase_jm_kick_all(kbdev);
1692 spin_unlock_irqrestore(&js_devdata->runpool_irq.lock, flags);
1693 up(&js_devdata->schedule_sem);
1697 * kbasep_vinstr_suspend_worker - worker suspending vinstr module
1698 * @data: pointer to work structure
1700 static void kbasep_vinstr_suspend_worker(struct work_struct *data)
1702 struct kbase_vinstr_context *vinstr_ctx;
1703 unsigned long flags;
1705 vinstr_ctx = container_of(data, struct kbase_vinstr_context,
1708 mutex_lock(&vinstr_ctx->lock);
1710 if (vinstr_ctx->kctx)
1711 disable_hwcnt(vinstr_ctx);
1713 spin_lock_irqsave(&vinstr_ctx->state_lock, flags);
1714 vinstr_ctx->state = VINSTR_SUSPENDED;
1715 wake_up_all(&vinstr_ctx->suspend_waitq);
1716 spin_unlock_irqrestore(&vinstr_ctx->state_lock, flags);
1718 mutex_unlock(&vinstr_ctx->lock);
1720 /* Kick GPU scheduler to allow entering protected mode.
1721 * This must happen after vinstr was suspended. */
1722 kbasep_vinstr_kick_scheduler(vinstr_ctx->kbdev);
1726 * kbasep_vinstr_suspend_worker - worker resuming vinstr module
1727 * @data: pointer to work structure
1729 static void kbasep_vinstr_resume_worker(struct work_struct *data)
1731 struct kbase_vinstr_context *vinstr_ctx;
1732 unsigned long flags;
1734 vinstr_ctx = container_of(data, struct kbase_vinstr_context,
1737 mutex_lock(&vinstr_ctx->lock);
1739 if (vinstr_ctx->kctx)
1740 enable_hwcnt(vinstr_ctx);
1742 spin_lock_irqsave(&vinstr_ctx->state_lock, flags);
1743 vinstr_ctx->state = VINSTR_IDLE;
1744 wake_up_all(&vinstr_ctx->suspend_waitq);
1745 spin_unlock_irqrestore(&vinstr_ctx->state_lock, flags);
1747 mutex_unlock(&vinstr_ctx->lock);
1749 /* Kick GPU scheduler to allow entering protected mode.
1750 * Note that scheduler state machine might requested re-entry to
1751 * protected mode before vinstr was resumed.
1752 * This must happen after vinstr was release. */
1753 kbasep_vinstr_kick_scheduler(vinstr_ctx->kbdev);
1756 /*****************************************************************************/
1758 struct kbase_vinstr_context *kbase_vinstr_init(struct kbase_device *kbdev)
1760 struct kbase_vinstr_context *vinstr_ctx;
1762 vinstr_ctx = kzalloc(sizeof(*vinstr_ctx), GFP_KERNEL);
1766 INIT_LIST_HEAD(&vinstr_ctx->idle_clients);
1767 INIT_LIST_HEAD(&vinstr_ctx->waiting_clients);
1768 mutex_init(&vinstr_ctx->lock);
1769 spin_lock_init(&vinstr_ctx->state_lock);
1770 vinstr_ctx->kbdev = kbdev;
1771 vinstr_ctx->thread = NULL;
1772 vinstr_ctx->state = VINSTR_IDLE;
1773 vinstr_ctx->suspend_cnt = 0;
1774 INIT_WORK(&vinstr_ctx->suspend_work, kbasep_vinstr_suspend_worker);
1775 INIT_WORK(&vinstr_ctx->resume_work, kbasep_vinstr_resume_worker);
1776 init_waitqueue_head(&vinstr_ctx->suspend_waitq);
1778 atomic_set(&vinstr_ctx->request_pending, 0);
1779 init_waitqueue_head(&vinstr_ctx->waitq);
1784 void kbase_vinstr_term(struct kbase_vinstr_context *vinstr_ctx)
1786 struct kbase_vinstr_client *cli;
1788 /* Stop service thread first. */
1789 if (vinstr_ctx->thread)
1790 kthread_stop(vinstr_ctx->thread);
1792 /* Wait for workers. */
1793 flush_work(&vinstr_ctx->suspend_work);
1794 flush_work(&vinstr_ctx->resume_work);
1797 struct list_head *list = &vinstr_ctx->idle_clients;
1799 if (list_empty(list)) {
1800 list = &vinstr_ctx->waiting_clients;
1801 if (list_empty(list))
1805 cli = list_first_entry(list, struct kbase_vinstr_client, list);
1806 list_del(&cli->list);
1807 kfree(cli->accum_buffer);
1809 vinstr_ctx->nclients--;
1811 KBASE_DEBUG_ASSERT(!vinstr_ctx->nclients);
1812 if (vinstr_ctx->kctx)
1813 kbasep_vinstr_destroy_kctx(vinstr_ctx);
1817 int kbase_vinstr_hwcnt_reader_setup(struct kbase_vinstr_context *vinstr_ctx,
1818 struct kbase_uk_hwcnt_reader_setup *setup)
1820 struct kbase_vinstr_client *cli;
1823 KBASE_DEBUG_ASSERT(vinstr_ctx);
1824 KBASE_DEBUG_ASSERT(setup);
1825 KBASE_DEBUG_ASSERT(setup->buffer_count);
1827 bitmap[SHADER_HWCNT_BM] = setup->shader_bm;
1828 bitmap[TILER_HWCNT_BM] = setup->tiler_bm;
1829 bitmap[MMU_L2_HWCNT_BM] = setup->mmu_l2_bm;
1830 bitmap[JM_HWCNT_BM] = setup->jm_bm;
1832 cli = kbasep_vinstr_attach_client(
1834 setup->buffer_count,
1845 int kbase_vinstr_legacy_hwc_setup(
1846 struct kbase_vinstr_context *vinstr_ctx,
1847 struct kbase_vinstr_client **cli,
1848 struct kbase_uk_hwcnt_setup *setup)
1850 KBASE_DEBUG_ASSERT(vinstr_ctx);
1851 KBASE_DEBUG_ASSERT(setup);
1852 KBASE_DEBUG_ASSERT(cli);
1854 if (setup->dump_buffer) {
1857 bitmap[SHADER_HWCNT_BM] = setup->shader_bm;
1858 bitmap[TILER_HWCNT_BM] = setup->tiler_bm;
1859 bitmap[MMU_L2_HWCNT_BM] = setup->mmu_l2_bm;
1860 bitmap[JM_HWCNT_BM] = setup->jm_bm;
1865 *cli = kbasep_vinstr_attach_client(
1869 (void *)(long)setup->dump_buffer,
1878 kbase_vinstr_detach_client(*cli);
1885 struct kbase_vinstr_client *kbase_vinstr_hwcnt_kernel_setup(
1886 struct kbase_vinstr_context *vinstr_ctx,
1887 struct kbase_uk_hwcnt_reader_setup *setup,
1888 void *kernel_buffer)
1892 if (!vinstr_ctx || !setup || !kernel_buffer)
1895 bitmap[SHADER_HWCNT_BM] = setup->shader_bm;
1896 bitmap[TILER_HWCNT_BM] = setup->tiler_bm;
1897 bitmap[MMU_L2_HWCNT_BM] = setup->mmu_l2_bm;
1898 bitmap[JM_HWCNT_BM] = setup->jm_bm;
1900 return kbasep_vinstr_attach_client(
1907 KBASE_EXPORT_TEST_API(kbase_vinstr_hwcnt_kernel_setup);
1909 int kbase_vinstr_hwc_dump(struct kbase_vinstr_client *cli,
1910 enum base_hwcnt_reader_event event_id)
1913 struct kbase_vinstr_context *vinstr_ctx;
1920 vinstr_ctx = cli->vinstr_ctx;
1921 KBASE_DEBUG_ASSERT(vinstr_ctx);
1923 KBASE_DEBUG_ASSERT(event_id < BASE_HWCNT_READER_EVENT_COUNT);
1924 event_mask = 1 << event_id;
1926 mutex_lock(&vinstr_ctx->lock);
1928 if (event_mask & cli->event_mask) {
1929 rcode = kbasep_vinstr_collect_and_accumulate(
1935 rcode = kbasep_vinstr_update_client(cli, timestamp, event_id);
1939 kbasep_vinstr_reprogram(vinstr_ctx);
1943 mutex_unlock(&vinstr_ctx->lock);
1947 KBASE_EXPORT_TEST_API(kbase_vinstr_hwc_dump);
1949 int kbase_vinstr_hwc_clear(struct kbase_vinstr_client *cli)
1951 struct kbase_vinstr_context *vinstr_ctx;
1958 vinstr_ctx = cli->vinstr_ctx;
1959 KBASE_DEBUG_ASSERT(vinstr_ctx);
1961 mutex_lock(&vinstr_ctx->lock);
1963 rcode = kbasep_vinstr_collect_and_accumulate(vinstr_ctx, &unused);
1966 rcode = kbase_instr_hwcnt_clear(vinstr_ctx->kctx);
1969 memset(cli->accum_buffer, 0, cli->dump_size);
1971 kbasep_vinstr_reprogram(vinstr_ctx);
1974 mutex_unlock(&vinstr_ctx->lock);
1979 int kbase_vinstr_try_suspend(struct kbase_vinstr_context *vinstr_ctx)
1981 unsigned long flags;
1984 KBASE_DEBUG_ASSERT(vinstr_ctx);
1986 spin_lock_irqsave(&vinstr_ctx->state_lock, flags);
1987 switch (vinstr_ctx->state) {
1988 case VINSTR_SUSPENDED:
1989 vinstr_ctx->suspend_cnt++;
1990 /* overflow shall not happen */
1991 BUG_ON(0 == vinstr_ctx->suspend_cnt);
1996 vinstr_ctx->state = VINSTR_SUSPENDING;
1997 schedule_work(&vinstr_ctx->suspend_work);
2000 case VINSTR_DUMPING:
2001 vinstr_ctx->state = VINSTR_SUSPENDING;
2004 case VINSTR_SUSPENDING:
2006 case VINSTR_RESUMING:
2013 spin_unlock_irqrestore(&vinstr_ctx->state_lock, flags);
2018 void kbase_vinstr_suspend(struct kbase_vinstr_context *vinstr_ctx)
2020 wait_event(vinstr_ctx->suspend_waitq,
2021 (0 == kbase_vinstr_try_suspend(vinstr_ctx)));
2024 void kbase_vinstr_resume(struct kbase_vinstr_context *vinstr_ctx)
2026 unsigned long flags;
2028 KBASE_DEBUG_ASSERT(vinstr_ctx);
2030 spin_lock_irqsave(&vinstr_ctx->state_lock, flags);
2031 BUG_ON(VINSTR_SUSPENDING == vinstr_ctx->state);
2032 if (VINSTR_SUSPENDED == vinstr_ctx->state) {
2033 BUG_ON(0 == vinstr_ctx->suspend_cnt);
2034 vinstr_ctx->suspend_cnt--;
2035 if (0 == vinstr_ctx->suspend_cnt) {
2036 vinstr_ctx->state = VINSTR_RESUMING;
2037 schedule_work(&vinstr_ctx->resume_work);
2040 spin_unlock_irqrestore(&vinstr_ctx->state_lock, flags);