15442bafdSRob Clark // SPDX-License-Identifier: GPL-2.0 25442bafdSRob Clark /* 35442bafdSRob Clark * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 45442bafdSRob Clark */ 55442bafdSRob Clark 65442bafdSRob Clark #ifndef __MSM_PERFCNTR_H__ 75442bafdSRob Clark #define __MSM_PERFCNTR_H__ 85442bafdSRob Clark 95442bafdSRob Clark #include "linux/array_size.h" 10*a7b378c9SRob Clark #include "linux/circ_buf.h" 11*a7b378c9SRob Clark #include "linux/hrtimer.h" 12*a7b378c9SRob Clark #include "linux/kthread.h" 13*a7b378c9SRob Clark #include "linux/wait.h" 14*a7b378c9SRob Clark #include "linux/workqueue.h" 155442bafdSRob Clark 165442bafdSRob Clark #include "adreno_common.xml.h" 175442bafdSRob Clark 185442bafdSRob Clark /* 195442bafdSRob Clark * This is a subset of the tables used by mesa. We don't need to 205442bafdSRob Clark * enumerate the countables on the kernel side. 215442bafdSRob Clark */ 225442bafdSRob Clark 235442bafdSRob Clark /* Describes a single counter: */ 245442bafdSRob Clark struct msm_perfcntr_counter { 255442bafdSRob Clark /* offset of the SELect register to choose what to count: */ 265442bafdSRob Clark unsigned select_reg; 275442bafdSRob Clark /* additional SEL regs to enable slice counters (gen8+) */ 285442bafdSRob Clark unsigned slice_select_regs[2]; 295442bafdSRob Clark /* offset of the lo/hi 32b to read current counter value: */ 305442bafdSRob Clark unsigned counter_reg_lo; 315442bafdSRob Clark unsigned counter_reg_hi; 325442bafdSRob Clark /* TODO some counters have enable/clear registers */ 335442bafdSRob Clark }; 345442bafdSRob Clark 355442bafdSRob Clark /* Describes an entire counter group: */ 365442bafdSRob Clark struct msm_perfcntr_group { 375442bafdSRob Clark const char *name; 385442bafdSRob Clark enum adreno_pipe pipe; 395442bafdSRob Clark unsigned num_counters; 405442bafdSRob Clark const struct msm_perfcntr_counter *counters; 415442bafdSRob Clark }; 425442bafdSRob Clark 438766dbc3SRob Clark /** 4402195633SRob Clark * struct msm_perfcntr_stream - state for a single open stream fd 4502195633SRob Clark */ 4602195633SRob Clark struct msm_perfcntr_stream { 4702195633SRob Clark /** @gpu: Back-link to the GPU */ 4802195633SRob Clark struct msm_gpu *gpu; 4902195633SRob Clark 50*a7b378c9SRob Clark /** @sample_timer: Timer to sample counters */ 51*a7b378c9SRob Clark struct hrtimer sample_timer; 52*a7b378c9SRob Clark 53*a7b378c9SRob Clark /** @poll_wq: Wait queue for waiting for OA data to be available */ 54*a7b378c9SRob Clark wait_queue_head_t poll_wq; 55*a7b378c9SRob Clark 56*a7b378c9SRob Clark /** @sample_period_ns: Sampling period */ 57*a7b378c9SRob Clark uint64_t sample_period_ns; 58*a7b378c9SRob Clark 5902195633SRob Clark /** @nr_groups: # of counter groups with enabled counters */ 6002195633SRob Clark uint32_t nr_groups; 6102195633SRob Clark 62*a7b378c9SRob Clark /** @seqno: counter for collected samples */ 63*a7b378c9SRob Clark uint32_t seqno; 64*a7b378c9SRob Clark 655eedc8c2SRob Clark /** @sel_fence: Fence for SEL reg programming */ 665eedc8c2SRob Clark uint32_t sel_fence; 675eedc8c2SRob Clark 6802195633SRob Clark /** 69*a7b378c9SRob Clark * @sel_work: Worker for SEL reg programming 70*a7b378c9SRob Clark * 71*a7b378c9SRob Clark * Initial SEL reg programming (as opposed to restoring the SEL 72*a7b378c9SRob Clark * regs on runpm resume) must run on the same ordered wq as is 73*a7b378c9SRob Clark * used by drm_sched, to serialize it with GEM_SUBMITs written 74*a7b378c9SRob Clark * into the same ringbuffer. 75*a7b378c9SRob Clark */ 76*a7b378c9SRob Clark struct work_struct sel_work; 77*a7b378c9SRob Clark 78*a7b378c9SRob Clark /** 79*a7b378c9SRob Clark * @sample_work: Worker for collecting samples 80*a7b378c9SRob Clark */ 81*a7b378c9SRob Clark struct kthread_work sample_work; 82*a7b378c9SRob Clark 83*a7b378c9SRob Clark /** 84*a7b378c9SRob Clark * @read_lock: 85*a7b378c9SRob Clark * 86*a7b378c9SRob Clark * Fifo access is synchronied on the producer side by virtue 87*a7b378c9SRob Clark * of there being a single timer collecting samples and writing 88*a7b378c9SRob Clark * into the fifo. It is protected on the consumer side by 89*a7b378c9SRob Clark * @read_lock. 90*a7b378c9SRob Clark */ 91*a7b378c9SRob Clark struct mutex read_lock; 92*a7b378c9SRob Clark 93*a7b378c9SRob Clark /** 9402195633SRob Clark * @group_idx: array of nr_groups 9502195633SRob Clark * 9602195633SRob Clark * Maps the order of groups in PERFCNTR_CONFIG ioctl to group idx, 9702195633SRob Clark * so that results in the results stream can be ordered to match 9802195633SRob Clark * the ioctl call that setup the stream 9902195633SRob Clark */ 10002195633SRob Clark uint32_t *group_idx; 101*a7b378c9SRob Clark 102*a7b378c9SRob Clark /** @fifo: circular buffer for samples */ 103*a7b378c9SRob Clark struct circ_buf fifo; 104*a7b378c9SRob Clark 105*a7b378c9SRob Clark /** @fifo_size: circular buffer size */ 106*a7b378c9SRob Clark size_t fifo_size; 107*a7b378c9SRob Clark 108*a7b378c9SRob Clark /** @period_size: size of data for single sampling period */ 109*a7b378c9SRob Clark size_t period_size; 11002195633SRob Clark }; 11102195633SRob Clark 11202195633SRob Clark uint32_t msm_perfcntr_group_idx(const struct msm_perfcntr_stream *stream, uint32_t n); 11302195633SRob Clark uint32_t msm_perfcntr_counter_base(const struct msm_perfcntr_stream *stream, uint32_t group_idx); 11402195633SRob Clark 11502195633SRob Clark /** 1168766dbc3SRob Clark * struct msm_perfcntr_context_state - per-msm_context counter state 1178766dbc3SRob Clark * 1188766dbc3SRob Clark * A given counter can either be unused, reserved for global counter 1198766dbc3SRob Clark * collection exclusively, or reserved for local per-context counter 1208766dbc3SRob Clark * collection inclusively. Multiple contexts can reserve the same 1218766dbc3SRob Clark * counter, since SEL reg programming and counter begin/end sampling 1228766dbc3SRob Clark * happen locally (within a single GEM_SUBMIT ioctl). 1238766dbc3SRob Clark */ 1248766dbc3SRob Clark struct msm_perfcntr_context_state { 1258766dbc3SRob Clark /** @dummy: Some compilers dislike structs with only a flex array */ 1268766dbc3SRob Clark unsigned dummy; 1278766dbc3SRob Clark 1288766dbc3SRob Clark /** 1298766dbc3SRob Clark * @reserved_counters: 1308766dbc3SRob Clark * 1318766dbc3SRob Clark * The number of reserved counters indexed by perfcntr group. 1328766dbc3SRob Clark */ 1338766dbc3SRob Clark unsigned reserved_counters[]; 1348766dbc3SRob Clark }; 1358766dbc3SRob Clark 136c897d550SRob Clark extern const struct msm_perfcntr_group a6xx_perfcntr_groups[]; 137c897d550SRob Clark extern const unsigned a6xx_num_perfcntr_groups; 138c897d550SRob Clark 139c897d550SRob Clark extern const struct msm_perfcntr_group a7xx_perfcntr_groups[]; 140c897d550SRob Clark extern const unsigned a7xx_num_perfcntr_groups; 141c897d550SRob Clark 142c897d550SRob Clark extern const struct msm_perfcntr_group a8xx_perfcntr_groups[]; 143c897d550SRob Clark extern const unsigned a8xx_num_perfcntr_groups; 144c897d550SRob Clark 1455442bafdSRob Clark #define GROUP(_name, _pipe, _counters, _countables) { \ 1465442bafdSRob Clark .name = _name, \ 1475442bafdSRob Clark .pipe = _pipe, \ 1485442bafdSRob Clark .num_counters = ARRAY_SIZE(_counters), \ 1495442bafdSRob Clark .counters = _counters, \ 1505442bafdSRob Clark } 1515442bafdSRob Clark 1525442bafdSRob Clark #define fd_perfcntr_counter msm_perfcntr_counter 1535442bafdSRob Clark #define fd_perfcntr_group msm_perfcntr_group 1545442bafdSRob Clark 1555442bafdSRob Clark #endif /* __MSM_PERFCNTR_H__ */ 156