mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
Add new UABI and implementation of PERFCNTR_CONFIG ioctl. A bit more work is required to configure the pwrup_reglist for the GMU to restore SELect regs on exit of IFPC, before we can stop disabling IFPC while global counter collection. This will follow in a later commit, but will be transparent to userspace. Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com> Reviewed-by: Anna Maniscalco <anna.maniscalco2000@gmail.com> Reviewed-by: Akhil P Oommen <akhilpo@oss.qualcomm.com> Patchwork: https://patchwork.freedesktop.org/patch/728217/ Message-ID: <20260526145137.160554-14-robin.clark@oss.qualcomm.com>
156 lines
4.5 KiB
C
156 lines
4.5 KiB
C
// 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__ */
|