1 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 /* 3 * 4 * (C) COPYRIGHT 2021-2022 ARM Limited. All rights reserved. 5 * 6 * This program is free software and is provided to you under the terms of the 7 * GNU General Public License version 2 as published by the Free Software 8 * Foundation, and any use by you of this program is subject to the terms 9 * of such GNU license. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, you can access it online at 18 * http://www.gnu.org/licenses/gpl-2.0.html. 19 * 20 */ 21 22 /* 23 * Virtual interface for CSF hardware counter backend. 24 */ 25 26 #ifndef _KBASE_HWCNT_BACKEND_CSF_IF_H_ 27 #define _KBASE_HWCNT_BACKEND_CSF_IF_H_ 28 29 #include <linux/types.h> 30 31 struct kbase_hwcnt_backend_csf_if_ctx; 32 33 struct kbase_hwcnt_backend_csf_if_ring_buf; 34 35 /** 36 * struct kbase_hwcnt_backend_csf_if_enable - enable hardware counter collection 37 * structure. 38 * @fe_bm: Front End counters selection bitmask. 39 * @shader_bm: Shader counters selection bitmask. 40 * @tiler_bm: Tiler counters selection bitmask. 41 * @mmu_l2_bm: MMU_L2 counters selection bitmask. 42 * @counter_set: The performance counter set to enable. 43 * @clk_enable_map: An array of u64 bitfields, each bit of which enables cycle 44 * counter for a given clock domain. 45 */ 46 struct kbase_hwcnt_backend_csf_if_enable { 47 u32 fe_bm; 48 u32 shader_bm; 49 u32 tiler_bm; 50 u32 mmu_l2_bm; 51 u8 counter_set; 52 u64 clk_enable_map; 53 }; 54 55 /** 56 * struct kbase_hwcnt_backend_csf_if_prfcnt_info - Performance counter 57 * information. 58 * @prfcnt_hw_size: Total length in bytes of all the hardware counters data. The hardware 59 * counters are sub-divided into 4 classes: front-end, shader, tiler, and 60 * memory system (l2 cache + MMU). 61 * @prfcnt_fw_size: Total length in bytes of all the firmware counters data. 62 * @dump_bytes: Bytes of GPU memory required to perform a performance 63 * counter dump. dump_bytes = prfcnt_hw_size + prfcnt_fw_size. 64 * @prfcnt_block_size: Bytes of each performance counter block. 65 * @l2_count: The MMU L2 cache count. 66 * @core_mask: Shader core mask. 67 * @clk_cnt: Clock domain count in the system. 68 * @clearing_samples: Indicates whether counters are cleared after each sample 69 * is taken. 70 */ 71 struct kbase_hwcnt_backend_csf_if_prfcnt_info { 72 size_t prfcnt_hw_size; 73 size_t prfcnt_fw_size; 74 size_t dump_bytes; 75 size_t prfcnt_block_size; 76 size_t l2_count; 77 u64 core_mask; 78 u8 clk_cnt; 79 bool clearing_samples; 80 }; 81 82 /** 83 * typedef kbase_hwcnt_backend_csf_if_assert_lock_held_fn - Assert that the 84 * backend spinlock is 85 * held. 86 * @ctx: Non-NULL pointer to a CSF context. 87 */ 88 typedef void 89 kbase_hwcnt_backend_csf_if_assert_lock_held_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx); 90 91 /** 92 * typedef kbase_hwcnt_backend_csf_if_lock_fn - Acquire backend spinlock. 93 * 94 * @ctx: Non-NULL pointer to a CSF context. 95 * @flags: Pointer to the memory location that would store the previous 96 * interrupt state. 97 */ 98 typedef void kbase_hwcnt_backend_csf_if_lock_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx, 99 unsigned long *flags); 100 101 /** 102 * typedef kbase_hwcnt_backend_csf_if_unlock_fn - Release backend spinlock. 103 * 104 * @ctx: Non-NULL pointer to a CSF context. 105 * @flags: Previously stored interrupt state when Scheduler interrupt 106 * spinlock was acquired. 107 */ 108 typedef void kbase_hwcnt_backend_csf_if_unlock_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx, 109 unsigned long flags); 110 111 /** 112 * typedef kbase_hwcnt_backend_csf_if_get_prfcnt_info_fn - Get performance 113 * counter information. 114 * @ctx: Non-NULL pointer to a CSF context. 115 * @prfcnt_info: Non-NULL pointer to struct where performance counter 116 * information should be stored. 117 */ 118 typedef void kbase_hwcnt_backend_csf_if_get_prfcnt_info_fn( 119 struct kbase_hwcnt_backend_csf_if_ctx *ctx, 120 struct kbase_hwcnt_backend_csf_if_prfcnt_info *prfcnt_info); 121 122 /** 123 * typedef kbase_hwcnt_backend_csf_if_ring_buf_alloc_fn - Allocate a ring buffer 124 * for CSF interface. 125 * @ctx: Non-NULL pointer to a CSF context. 126 * @buf_count: The buffer count in the ring buffer to be allocated, 127 * MUST be power of 2. 128 * @cpu_dump_base: Non-NULL pointer to where ring buffer CPU base address is 129 * stored when success. 130 * @ring_buf: Non-NULL pointer to where ring buffer is stored when success. 131 * 132 * A ring buffer is needed by the CSF interface to do manual HWC sample and 133 * automatic HWC samples, the buffer count in the ring buffer MUST be power 134 * of 2 to meet the hardware requirement. 135 * 136 * Return: 0 on success, else error code. 137 */ 138 typedef int 139 kbase_hwcnt_backend_csf_if_ring_buf_alloc_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx, 140 u32 buf_count, void **cpu_dump_base, 141 struct kbase_hwcnt_backend_csf_if_ring_buf **ring_buf); 142 143 /** 144 * typedef kbase_hwcnt_backend_csf_if_ring_buf_sync_fn - Sync HWC dump buffers 145 * memory. 146 * @ctx: Non-NULL pointer to a CSF context. 147 * @ring_buf: Non-NULL pointer to the ring buffer. 148 * @buf_index_first: The first buffer index in the ring buffer to be synced, 149 * inclusive. 150 * @buf_index_last: The last buffer index in the ring buffer to be synced, 151 * exclusive. 152 * @for_cpu: The direction of sync to be applied, set to true when CPU 153 * cache needs invalidating before reading the buffer, and set 154 * to false after CPU writes to flush these before this memory 155 * is overwritten by the GPU. 156 * 157 * Flush cached HWC dump buffer data to ensure that all writes from GPU and CPU 158 * are correctly observed. 159 */ 160 typedef void 161 kbase_hwcnt_backend_csf_if_ring_buf_sync_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx, 162 struct kbase_hwcnt_backend_csf_if_ring_buf *ring_buf, 163 u32 buf_index_first, u32 buf_index_last, bool for_cpu); 164 165 /** 166 * typedef kbase_hwcnt_backend_csf_if_ring_buf_free_fn - Free a ring buffer for 167 * the CSF interface. 168 * 169 * @ctx: Non-NULL pointer to a CSF interface context. 170 * @ring_buf: Non-NULL pointer to the ring buffer which to be freed. 171 */ 172 typedef void 173 kbase_hwcnt_backend_csf_if_ring_buf_free_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx, 174 struct kbase_hwcnt_backend_csf_if_ring_buf *ring_buf); 175 176 /** 177 * typedef kbase_hwcnt_backend_csf_if_timestamp_ns_fn - Get the current 178 * timestamp of the CSF 179 * interface. 180 * @ctx: Non-NULL pointer to a CSF interface context. 181 * 182 * Return: CSF interface timestamp in nanoseconds. 183 */ 184 typedef u64 kbase_hwcnt_backend_csf_if_timestamp_ns_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx); 185 186 /** 187 * typedef kbase_hwcnt_backend_csf_if_dump_enable_fn - Setup and enable hardware 188 * counter in CSF interface. 189 * @ctx: Non-NULL pointer to a CSF interface context. 190 * @ring_buf: Non-NULL pointer to the ring buffer which used to setup the HWC. 191 * @enable: Non-NULL pointer to the enable map of HWC. 192 * 193 * Requires lock to be taken before calling. 194 */ 195 typedef void 196 kbase_hwcnt_backend_csf_if_dump_enable_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx, 197 struct kbase_hwcnt_backend_csf_if_ring_buf *ring_buf, 198 struct kbase_hwcnt_backend_csf_if_enable *enable); 199 200 /** 201 * typedef kbase_hwcnt_backend_csf_if_dump_disable_fn - Disable hardware counter 202 * in CSF interface. 203 * @ctx: Non-NULL pointer to a CSF interface context. 204 * 205 * Requires lock to be taken before calling. 206 */ 207 typedef void kbase_hwcnt_backend_csf_if_dump_disable_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx); 208 209 /** 210 * typedef kbase_hwcnt_backend_csf_if_dump_request_fn - Request a HWC dump. 211 * 212 * @ctx: Non-NULL pointer to the interface context. 213 * 214 * Requires lock to be taken before calling. 215 */ 216 typedef void kbase_hwcnt_backend_csf_if_dump_request_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx); 217 218 /** 219 * typedef kbase_hwcnt_backend_csf_if_get_indexes_fn - Get current extract and 220 * insert indexes of the 221 * ring buffer. 222 * 223 * @ctx: Non-NULL pointer to a CSF interface context. 224 * @extract_index: Non-NULL pointer where current extract index to be saved. 225 * @insert_index: Non-NULL pointer where current insert index to be saved. 226 * 227 * Requires lock to be taken before calling. 228 */ 229 typedef void kbase_hwcnt_backend_csf_if_get_indexes_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx, 230 u32 *extract_index, u32 *insert_index); 231 232 /** 233 * typedef kbase_hwcnt_backend_csf_if_set_extract_index_fn - Update the extract 234 * index of the ring 235 * buffer. 236 * 237 * @ctx: Non-NULL pointer to a CSF interface context. 238 * @extract_index: New extract index to be set. 239 * 240 * Requires lock to be taken before calling. 241 */ 242 typedef void 243 kbase_hwcnt_backend_csf_if_set_extract_index_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx, 244 u32 extract_index); 245 246 /** 247 * typedef kbase_hwcnt_backend_csf_if_get_gpu_cycle_count_fn - Get the current 248 * GPU cycle count. 249 * @ctx: Non-NULL pointer to a CSF interface context. 250 * @cycle_counts: Non-NULL pointer to an array where cycle counts to be saved, 251 * the array size should be at least as big as the number of 252 * clock domains returned by get_prfcnt_info interface. 253 * @clk_enable_map: An array of bitfields, each bit specifies an enabled clock 254 * domain. 255 * 256 * Requires lock to be taken before calling. 257 */ 258 typedef void 259 kbase_hwcnt_backend_csf_if_get_gpu_cycle_count_fn(struct kbase_hwcnt_backend_csf_if_ctx *ctx, 260 u64 *cycle_counts, u64 clk_enable_map); 261 262 /** 263 * struct kbase_hwcnt_backend_csf_if - Hardware counter backend CSF virtual 264 * interface. 265 * @ctx: CSF interface context. 266 * @assert_lock_held: Function ptr to assert backend spinlock is held. 267 * @lock: Function ptr to acquire backend spinlock. 268 * @unlock: Function ptr to release backend spinlock. 269 * @get_prfcnt_info: Function ptr to get performance counter related 270 * information. 271 * @ring_buf_alloc: Function ptr to allocate ring buffer for CSF HWC. 272 * @ring_buf_sync: Function ptr to sync ring buffer to CPU. 273 * @ring_buf_free: Function ptr to free ring buffer for CSF HWC. 274 * @timestamp_ns: Function ptr to get the current CSF interface 275 * timestamp. 276 * @dump_enable: Function ptr to enable dumping. 277 * @dump_disable: Function ptr to disable dumping. 278 * @dump_request: Function ptr to request a dump. 279 * @get_indexes: Function ptr to get extract and insert indexes of the 280 * ring buffer. 281 * @set_extract_index: Function ptr to set extract index of ring buffer. 282 * @get_gpu_cycle_count: Function ptr to get the GPU cycle count. 283 */ 284 struct kbase_hwcnt_backend_csf_if { 285 struct kbase_hwcnt_backend_csf_if_ctx *ctx; 286 kbase_hwcnt_backend_csf_if_assert_lock_held_fn *assert_lock_held; 287 kbase_hwcnt_backend_csf_if_lock_fn *lock; 288 kbase_hwcnt_backend_csf_if_unlock_fn *unlock; 289 kbase_hwcnt_backend_csf_if_get_prfcnt_info_fn *get_prfcnt_info; 290 kbase_hwcnt_backend_csf_if_ring_buf_alloc_fn *ring_buf_alloc; 291 kbase_hwcnt_backend_csf_if_ring_buf_sync_fn *ring_buf_sync; 292 kbase_hwcnt_backend_csf_if_ring_buf_free_fn *ring_buf_free; 293 kbase_hwcnt_backend_csf_if_timestamp_ns_fn *timestamp_ns; 294 kbase_hwcnt_backend_csf_if_dump_enable_fn *dump_enable; 295 kbase_hwcnt_backend_csf_if_dump_disable_fn *dump_disable; 296 kbase_hwcnt_backend_csf_if_dump_request_fn *dump_request; 297 kbase_hwcnt_backend_csf_if_get_indexes_fn *get_indexes; 298 kbase_hwcnt_backend_csf_if_set_extract_index_fn *set_extract_index; 299 kbase_hwcnt_backend_csf_if_get_gpu_cycle_count_fn *get_gpu_cycle_count; 300 }; 301 302 #endif /* #define _KBASE_HWCNT_BACKEND_CSF_IF_H_ */ 303