| // SPDX-License-Identifier: GPL-2.0 | |
| /* | |
| * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. | |
| */ | |
| #ifndef __MSM_PERFCNTR_H__ | |
| #define __MSM_PERFCNTR_H__ | |
| #include "linux/array_size.h" | |
| #include "linux/circ_buf.h" | |
| #include "linux/hrtimer.h" | |
| #include "linux/kthread.h" | |
| #include "linux/wait.h" | |
| #include "linux/workqueue.h" | |
| #include "adreno_common.xml.h" | |
| /* | |
| * This is a subset of the tables used by mesa. We don't need to | |
| * enumerate the countables on the kernel side. | |
| */ | |
| /* Describes a single counter: */ | |
| struct msm_perfcntr_counter { | |
| /* offset of the SELect register to choose what to count: */ | |
| unsigned select_reg; | |
| /* additional SEL regs to enable slice counters (gen8+) */ | |
| unsigned slice_select_regs[2]; | |
| /* offset of the lo/hi 32b to read current counter value: */ | |
| unsigned counter_reg_lo; | |
| unsigned counter_reg_hi; | |
| /* TODO some counters have enable/clear registers */ | |
| }; | |
| /* Describes an entire counter group: */ | |
| struct msm_perfcntr_group { | |
| const char *name; | |
| enum adreno_pipe pipe; | |
| unsigned num_counters; | |
| const struct msm_perfcntr_counter *counters; | |
| }; | |
| /** | |
| * struct msm_perfcntr_stream - state for a single open stream fd | |
| */ | |
| struct msm_perfcntr_stream { | |
| /** @gpu: Back-link to the GPU */ | |
| struct msm_gpu *gpu; | |
| /** @sample_timer: Timer to sample counters */ | |
| struct hrtimer sample_timer; | |
| /** @poll_wq: Wait queue for waiting for OA data to be available */ | |
| wait_queue_head_t poll_wq; | |
| /** @sample_period_ns: Sampling period */ | |
| uint64_t sample_period_ns; | |
| /** @nr_groups: # of counter groups with enabled counters */ | |
| uint32_t nr_groups; | |
| /** @seqno: counter for collected samples */ | |
| uint32_t seqno; | |
| /** @sel_fence: Fence for SEL reg programming */ | |
| uint32_t sel_fence; | |
| /** | |
| * @sel_work: Worker for SEL reg programming | |
| * | |
| * Initial SEL reg programming (as opposed to restoring the SEL | |
| * regs on runpm resume) must run on the same ordered wq as is | |
| * used by drm_sched, to serialize it with GEM_SUBMITs written | |
| * into the same ringbuffer. | |
| */ | |
| struct work_struct sel_work; | |
| /** | |
| * @sample_work: Worker for collecting samples | |
| */ | |
| struct kthread_work sample_work; | |
| /** | |
| * @read_lock: | |
| * | |
| * Fifo access is synchronied on the producer side by virtue | |
| * of there being a single timer collecting samples and writing | |
| * into the fifo. It is protected on the consumer side by | |
| * @read_lock. | |
| */ | |
| struct mutex read_lock; | |
| /** | |
| * @group_idx: array of nr_groups | |
| * | |
| * Maps the order of groups in PERFCNTR_CONFIG ioctl to group idx, | |
| * so that results in the results stream can be ordered to match | |
| * the ioctl call that setup the stream | |
| */ | |
| uint32_t *group_idx; | |
| /** @fifo: circular buffer for samples */ | |
| struct circ_buf fifo; | |
| /** @fifo_size: circular buffer size */ | |
| size_t fifo_size; | |
| /** @period_size: size of data for single sampling period */ | |
| size_t period_size; | |
| }; | |
| uint32_t msm_perfcntr_group_idx(const struct msm_perfcntr_stream *stream, uint32_t n); | |
| uint32_t msm_perfcntr_counter_base(const struct msm_perfcntr_stream *stream, uint32_t group_idx); | |
| /** | |
| * struct msm_perfcntr_context_state - per-msm_context counter state | |
| * | |
| * A given counter can either be unused, reserved for global counter | |
| * collection exclusively, or reserved for local per-context counter | |
| * collection inclusively. Multiple contexts can reserve the same | |
| * counter, since SEL reg programming and counter begin/end sampling | |
| * happen locally (within a single GEM_SUBMIT ioctl). | |
| */ | |
| struct msm_perfcntr_context_state { | |
| /** @dummy: Some compilers dislike structs with only a flex array */ | |
| unsigned dummy; | |
| /** | |
| * @reserved_counters: | |
| * | |
| * The number of reserved counters indexed by perfcntr group. | |
| */ | |
| unsigned reserved_counters[]; | |
| }; | |
| extern const struct msm_perfcntr_group a6xx_perfcntr_groups[]; | |
| extern const unsigned a6xx_num_perfcntr_groups; | |
| extern const struct msm_perfcntr_group a7xx_perfcntr_groups[]; | |
| extern const unsigned a7xx_num_perfcntr_groups; | |
| extern const struct msm_perfcntr_group a8xx_perfcntr_groups[]; | |
| extern const unsigned a8xx_num_perfcntr_groups; | |
| #define GROUP(_name, _pipe, _counters, _countables) { \ | |
| .name = _name, \ | |
| .pipe = _pipe, \ | |
| .num_counters = ARRAY_SIZE(_counters), \ | |
| .counters = _counters, \ | |
| } | |
| #define fd_perfcntr_counter msm_perfcntr_counter | |
| #define fd_perfcntr_group msm_perfcntr_group | |
| #endif /* __MSM_PERFCNTR_H__ */ |