1 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
2 /*
3 *
4 * (C) COPYRIGHT 2021-2023 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 #include "hwcnt/backend/mali_kbase_hwcnt_backend_csf.h"
23 #include "hwcnt/mali_kbase_hwcnt_gpu.h"
24 #include "hwcnt/mali_kbase_hwcnt_types.h"
25
26 #include <linux/log2.h>
27 #include <linux/kernel.h>
28 #include <linux/sched.h>
29 #include <linux/slab.h>
30 #include <linux/spinlock.h>
31 #include <linux/wait.h>
32 #include <linux/workqueue.h>
33 #include <linux/completion.h>
34
35 #ifndef BASE_MAX_NR_CLOCKS_REGULATORS
36 #define BASE_MAX_NR_CLOCKS_REGULATORS 4
37 #endif
38
39 #if IS_ENABLED(CONFIG_MALI_IS_FPGA) && !IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI)
40 /* Backend watch dog timer interval in milliseconds: 18 seconds. */
41 #define HWCNT_BACKEND_WATCHDOG_TIMER_INTERVAL_MS ((u32)18000)
42 #else
43 /* Backend watch dog timer interval in milliseconds: 1 second. */
44 #define HWCNT_BACKEND_WATCHDOG_TIMER_INTERVAL_MS ((u32)1000)
45 #endif /* IS_FPGA && !NO_MALI */
46
47 /**
48 * enum kbase_hwcnt_backend_csf_dump_state - HWC CSF backend dumping states.
49 *
50 * @KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE: Initial state, or the state if there is
51 * an error.
52 *
53 * @KBASE_HWCNT_BACKEND_CSF_DUMP_REQUESTED: A user dump has been requested and
54 * we are waiting for an ACK, this ACK could come from either PRFCNT_ACK,
55 * PROTMODE_ENTER_ACK, or if an error occurs.
56 *
57 * @KBASE_HWCNT_BACKEND_CSF_DUMP_WATCHDOG_REQUESTED: A watchdog dump has been
58 * requested and we're waiting for an ACK - this ACK could come from either
59 * PRFCNT_ACK, or if an error occurs, PROTMODE_ENTER_ACK is not applied here
60 * since watchdog request can't be triggered in protected mode.
61 *
62 * @KBASE_HWCNT_BACKEND_CSF_DUMP_QUERYING_INSERT: Checking the insert
63 * immediately after receiving the ACK, so we know which index corresponds to
64 * the buffer we requested.
65 *
66 * @KBASE_HWCNT_BACKEND_CSF_DUMP_WORKER_LAUNCHED: The insert has been saved and
67 * now we have kicked off the worker.
68 *
69 * @KBASE_HWCNT_BACKEND_CSF_DUMP_ACCUMULATING: The insert has been saved and now
70 * we have kicked off the worker to accumulate up to that insert and then copy
71 * the delta to the user buffer to prepare for dump_get().
72 *
73 * @KBASE_HWCNT_BACKEND_CSF_DUMP_COMPLETED: The dump completed successfully.
74 *
75 * Valid state transitions:
76 * IDLE -> REQUESTED (on user dump request)
77 * IDLE -> WATCHDOG_REQUESTED (on watchdog request)
78 * IDLE -> QUERYING_INSERT (on user dump request in protected mode)
79 * REQUESTED -> QUERYING_INSERT (on dump acknowledged from firmware)
80 * WATCHDOG_REQUESTED -> REQUESTED (on user dump request)
81 * WATCHDOG_REQUESTED -> COMPLETED (on dump acknowledged from firmware for watchdog request)
82 * QUERYING_INSERT -> WORKER_LAUNCHED (on worker submission)
83 * WORKER_LAUNCHED -> ACCUMULATING (while the worker is accumulating)
84 * ACCUMULATING -> COMPLETED (on accumulation completion)
85 * COMPLETED -> QUERYING_INSERT (on user dump request in protected mode)
86 * COMPLETED -> REQUESTED (on user dump request)
87 * COMPLETED -> WATCHDOG_REQUESTED (on watchdog request)
88 * COMPLETED -> IDLE (on disable)
89 * ANY -> IDLE (on error)
90 */
91 enum kbase_hwcnt_backend_csf_dump_state {
92 KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE,
93 KBASE_HWCNT_BACKEND_CSF_DUMP_REQUESTED,
94 KBASE_HWCNT_BACKEND_CSF_DUMP_WATCHDOG_REQUESTED,
95 KBASE_HWCNT_BACKEND_CSF_DUMP_QUERYING_INSERT,
96 KBASE_HWCNT_BACKEND_CSF_DUMP_WORKER_LAUNCHED,
97 KBASE_HWCNT_BACKEND_CSF_DUMP_ACCUMULATING,
98 KBASE_HWCNT_BACKEND_CSF_DUMP_COMPLETED,
99 };
100
101 /**
102 * enum kbase_hwcnt_backend_csf_enable_state - HWC CSF backend enable states.
103 *
104 * @KBASE_HWCNT_BACKEND_CSF_DISABLED: Initial state, and the state when backend
105 * is disabled.
106 *
107 * @KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_ENABLED: Enable request is in
108 * progress, waiting for firmware acknowledgment.
109 *
110 * @KBASE_HWCNT_BACKEND_CSF_ENABLED: Enable request has been acknowledged,
111 * enable is done.
112 *
113 * @KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_DISABLED: Disable request is in
114 * progress, waiting for firmware acknowledgment.
115 *
116 * @KBASE_HWCNT_BACKEND_CSF_DISABLED_WAIT_FOR_WORKER: Disable request has been
117 * acknowledged, waiting for dump workers to be finished.
118 *
119 * @KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR_WAIT_FOR_WORKER: An
120 * unrecoverable error happened, waiting for dump workers to be finished.
121 *
122 * @KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR: An unrecoverable error
123 * happened, and dump workers have finished, waiting for reset.
124 *
125 * Valid state transitions:
126 * DISABLED -> TRANSITIONING_TO_ENABLED (on enable)
127 * TRANSITIONING_TO_ENABLED -> ENABLED (on enable ack)
128 * ENABLED -> TRANSITIONING_TO_DISABLED (on disable)
129 * TRANSITIONING_TO_DISABLED -> DISABLED_WAIT_FOR_WORKER (on disable ack)
130 * DISABLED_WAIT_FOR_WORKER -> DISABLED (after workers are flushed)
131 * DISABLED -> UNRECOVERABLE_ERROR (on unrecoverable error)
132 * ANY but DISABLED -> UNRECOVERABLE_ERROR_WAIT_FOR_WORKER (on unrecoverable
133 * error)
134 * UNRECOVERABLE_ERROR -> DISABLED (on before reset)
135 */
136 enum kbase_hwcnt_backend_csf_enable_state {
137 KBASE_HWCNT_BACKEND_CSF_DISABLED,
138 KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_ENABLED,
139 KBASE_HWCNT_BACKEND_CSF_ENABLED,
140 KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_DISABLED,
141 KBASE_HWCNT_BACKEND_CSF_DISABLED_WAIT_FOR_WORKER,
142 KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR_WAIT_FOR_WORKER,
143 KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR,
144 };
145
146 /**
147 * struct kbase_hwcnt_backend_csf_info - Information used to create an instance
148 * of a CSF hardware counter backend.
149 * @backend: Pointer to access CSF backend.
150 * @fw_in_protected_mode: True if FW is running in protected mode, else
151 * false.
152 * @unrecoverable_error_happened: True if an recoverable error happened, else
153 * false.
154 * @csf_if: CSF interface object pointer.
155 * @ring_buf_cnt: Dump buffer count in the ring buffer.
156 * @counter_set: The performance counter set to use.
157 * @metadata: Hardware counter metadata.
158 * @prfcnt_info: Performance counter information.
159 * @watchdog_if: Watchdog interface object pointer.
160 */
161 struct kbase_hwcnt_backend_csf_info {
162 struct kbase_hwcnt_backend_csf *backend;
163 bool fw_in_protected_mode;
164 bool unrecoverable_error_happened;
165 struct kbase_hwcnt_backend_csf_if *csf_if;
166 u32 ring_buf_cnt;
167 enum kbase_hwcnt_set counter_set;
168 const struct kbase_hwcnt_metadata *metadata;
169 struct kbase_hwcnt_backend_csf_if_prfcnt_info prfcnt_info;
170 struct kbase_hwcnt_watchdog_interface *watchdog_if;
171 };
172
173 /**
174 * struct kbase_hwcnt_csf_physical_layout - HWC sample memory physical layout
175 * information.
176 * @hw_block_cnt: Total number of hardware counters blocks. The hw counters blocks are
177 * sub-categorized into 4 classes: front-end, tiler, memory system, and shader.
178 * hw_block_cnt = fe_cnt + tiler_cnt + mmu_l2_cnt + shader_cnt.
179 * @fe_cnt: Front end block count.
180 * @tiler_cnt: Tiler block count.
181 * @mmu_l2_cnt: Memory system (MMU and L2 cache) block count.
182 * @shader_cnt: Shader Core block count.
183 * @fw_block_cnt: Total number of firmware counters blocks.
184 * @block_cnt: Total block count (sum of all counter blocks: hw_block_cnt + fw_block_cnt).
185 * @shader_avail_mask: Bitmap of all shader cores in the system.
186 * @enable_mask_offset: Offset in array elements of enable mask in each block
187 * starting from the beginning of block.
188 * @headers_per_block: For any block, the number of counters designated as block's header.
189 * @counters_per_block: For any block, the number of counters designated as block's payload.
190 * @values_per_block: For any block, the number of counters in total (header + payload).
191 */
192 struct kbase_hwcnt_csf_physical_layout {
193 u8 hw_block_cnt;
194 u8 fe_cnt;
195 u8 tiler_cnt;
196 u8 mmu_l2_cnt;
197 u8 shader_cnt;
198 u8 fw_block_cnt;
199 u8 block_cnt;
200 u64 shader_avail_mask;
201 size_t enable_mask_offset;
202 size_t headers_per_block;
203 size_t counters_per_block;
204 size_t values_per_block;
205 };
206
207 /**
208 * struct kbase_hwcnt_backend_csf - Instance of a CSF hardware counter backend.
209 * @info: CSF Info used to create the backend.
210 * @dump_state: The dumping state of the backend.
211 * @enable_state: The CSF backend internal enabled state.
212 * @insert_index_to_accumulate: The insert index in the ring buffer which need
213 * to accumulate up to.
214 * @enable_state_waitq: Wait queue object used to notify the enable
215 * changing flag is done.
216 * @to_user_buf: HWC sample buffer for client user, size
217 * metadata.dump_buf_bytes.
218 * @accum_buf: HWC sample buffer used as an internal
219 * accumulator, size metadata.dump_buf_bytes.
220 * @old_sample_buf: HWC sample buffer to save the previous values
221 * for delta calculation, size
222 * prfcnt_info.dump_bytes.
223 * @watchdog_last_seen_insert_idx: The insert index which watchdog has last
224 * seen, to check any new firmware automatic
225 * samples generated during the watchdog
226 * period.
227 * @ring_buf: Opaque pointer for ring buffer object.
228 * @ring_buf_cpu_base: CPU base address of the allocated ring buffer.
229 * @clk_enable_map: The enable map specifying enabled clock domains.
230 * @cycle_count_elapsed: Cycle count elapsed for a given sample period.
231 * @prev_cycle_count: Previous cycle count to calculate the cycle
232 * count for sample period.
233 * @phys_layout: Physical memory layout information of HWC
234 * sample buffer.
235 * @dump_completed: Completion signaled by the dump worker when
236 * it is completed accumulating up to the
237 * insert_index_to_accumulate.
238 * Should be initialized to the "complete" state.
239 * @user_requested: Flag to indicate a dump_request called from
240 * user.
241 * @hwc_dump_workq: Single threaded work queue for HWC workers
242 * execution.
243 * @hwc_dump_work: Worker to accumulate samples.
244 * @hwc_threshold_work: Worker for consuming available samples when
245 * threshold interrupt raised.
246 */
247 struct kbase_hwcnt_backend_csf {
248 struct kbase_hwcnt_backend_csf_info *info;
249 enum kbase_hwcnt_backend_csf_dump_state dump_state;
250 enum kbase_hwcnt_backend_csf_enable_state enable_state;
251 u32 insert_index_to_accumulate;
252 wait_queue_head_t enable_state_waitq;
253 u64 *to_user_buf;
254 u64 *accum_buf;
255 u32 *old_sample_buf;
256 u32 watchdog_last_seen_insert_idx;
257 struct kbase_hwcnt_backend_csf_if_ring_buf *ring_buf;
258 void *ring_buf_cpu_base;
259 u64 clk_enable_map;
260 u64 cycle_count_elapsed[BASE_MAX_NR_CLOCKS_REGULATORS];
261 u64 prev_cycle_count[BASE_MAX_NR_CLOCKS_REGULATORS];
262 struct kbase_hwcnt_csf_physical_layout phys_layout;
263 struct completion dump_completed;
264 bool user_requested;
265 struct workqueue_struct *hwc_dump_workq;
266 struct work_struct hwc_dump_work;
267 struct work_struct hwc_threshold_work;
268 };
269
kbasep_hwcnt_backend_csf_backend_exists(struct kbase_hwcnt_backend_csf_info * csf_info)270 static bool kbasep_hwcnt_backend_csf_backend_exists(struct kbase_hwcnt_backend_csf_info *csf_info)
271 {
272 WARN_ON(!csf_info);
273 csf_info->csf_if->assert_lock_held(csf_info->csf_if->ctx);
274 return (csf_info->backend != NULL);
275 }
276
277 /**
278 * kbasep_hwcnt_backend_csf_cc_initial_sample() - Initialize cycle count
279 * tracking.
280 *
281 * @backend_csf: Non-NULL pointer to backend.
282 * @enable_map: Non-NULL pointer to enable map specifying enabled counters.
283 */
284 static void
kbasep_hwcnt_backend_csf_cc_initial_sample(struct kbase_hwcnt_backend_csf * backend_csf,const struct kbase_hwcnt_enable_map * enable_map)285 kbasep_hwcnt_backend_csf_cc_initial_sample(struct kbase_hwcnt_backend_csf *backend_csf,
286 const struct kbase_hwcnt_enable_map *enable_map)
287 {
288 u64 clk_enable_map = enable_map->clk_enable_map;
289 u64 cycle_counts[BASE_MAX_NR_CLOCKS_REGULATORS];
290 size_t clk;
291
292 memset(cycle_counts, 0, sizeof(cycle_counts));
293
294 /* Read cycle count from CSF interface for both clock domains. */
295 backend_csf->info->csf_if->get_gpu_cycle_count(backend_csf->info->csf_if->ctx, cycle_counts,
296 clk_enable_map);
297
298 kbase_hwcnt_metadata_for_each_clock(enable_map->metadata, clk)
299 {
300 if (kbase_hwcnt_clk_enable_map_enabled(clk_enable_map, clk))
301 backend_csf->prev_cycle_count[clk] = cycle_counts[clk];
302 }
303
304 /* Keep clk_enable_map for dump_request. */
305 backend_csf->clk_enable_map = clk_enable_map;
306 }
307
kbasep_hwcnt_backend_csf_cc_update(struct kbase_hwcnt_backend_csf * backend_csf)308 static void kbasep_hwcnt_backend_csf_cc_update(struct kbase_hwcnt_backend_csf *backend_csf)
309 {
310 u64 cycle_counts[BASE_MAX_NR_CLOCKS_REGULATORS];
311 size_t clk;
312
313 memset(cycle_counts, 0, sizeof(cycle_counts));
314
315 backend_csf->info->csf_if->assert_lock_held(backend_csf->info->csf_if->ctx);
316
317 backend_csf->info->csf_if->get_gpu_cycle_count(backend_csf->info->csf_if->ctx, cycle_counts,
318 backend_csf->clk_enable_map);
319
320 kbase_hwcnt_metadata_for_each_clock(backend_csf->info->metadata, clk)
321 {
322 if (kbase_hwcnt_clk_enable_map_enabled(backend_csf->clk_enable_map, clk)) {
323 backend_csf->cycle_count_elapsed[clk] =
324 cycle_counts[clk] - backend_csf->prev_cycle_count[clk];
325 backend_csf->prev_cycle_count[clk] = cycle_counts[clk];
326 }
327 }
328 }
329
330 /* CSF backend implementation of kbase_hwcnt_backend_timestamp_ns_fn */
kbasep_hwcnt_backend_csf_timestamp_ns(struct kbase_hwcnt_backend * backend)331 static u64 kbasep_hwcnt_backend_csf_timestamp_ns(struct kbase_hwcnt_backend *backend)
332 {
333 struct kbase_hwcnt_backend_csf *backend_csf = (struct kbase_hwcnt_backend_csf *)backend;
334
335 if (!backend_csf || !backend_csf->info || !backend_csf->info->csf_if)
336 return 0;
337
338 return backend_csf->info->csf_if->timestamp_ns(backend_csf->info->csf_if->ctx);
339 }
340
341 /** kbasep_hwcnt_backend_csf_process_enable_map() - Process the enable_map to
342 * guarantee headers are
343 * enabled if any counter is
344 * required.
345 *@phys_enable_map: HWC physical enable map to be processed.
346 */
347 static void
kbasep_hwcnt_backend_csf_process_enable_map(struct kbase_hwcnt_physical_enable_map * phys_enable_map)348 kbasep_hwcnt_backend_csf_process_enable_map(struct kbase_hwcnt_physical_enable_map *phys_enable_map)
349 {
350 WARN_ON(!phys_enable_map);
351
352 /* Enable header if any counter is required from user, the header is
353 * controlled by bit 0 of the enable mask.
354 */
355 if (phys_enable_map->fe_bm)
356 phys_enable_map->fe_bm |= 1;
357
358 if (phys_enable_map->tiler_bm)
359 phys_enable_map->tiler_bm |= 1;
360
361 if (phys_enable_map->mmu_l2_bm)
362 phys_enable_map->mmu_l2_bm |= 1;
363
364 if (phys_enable_map->shader_bm)
365 phys_enable_map->shader_bm |= 1;
366 }
367
kbasep_hwcnt_backend_csf_init_layout(const struct kbase_hwcnt_backend_csf_if_prfcnt_info * prfcnt_info,struct kbase_hwcnt_csf_physical_layout * phys_layout)368 static void kbasep_hwcnt_backend_csf_init_layout(
369 const struct kbase_hwcnt_backend_csf_if_prfcnt_info *prfcnt_info,
370 struct kbase_hwcnt_csf_physical_layout *phys_layout)
371 {
372 size_t shader_core_cnt;
373 size_t values_per_block;
374 size_t fw_blocks_count;
375 size_t hw_blocks_count;
376
377 WARN_ON(!prfcnt_info);
378 WARN_ON(!phys_layout);
379
380 shader_core_cnt = fls64(prfcnt_info->core_mask);
381 values_per_block = prfcnt_info->prfcnt_block_size / KBASE_HWCNT_VALUE_HW_BYTES;
382 fw_blocks_count = div_u64(prfcnt_info->prfcnt_fw_size, prfcnt_info->prfcnt_block_size);
383 hw_blocks_count = div_u64(prfcnt_info->prfcnt_hw_size, prfcnt_info->prfcnt_block_size);
384
385 /* The number of hardware counters reported by the GPU matches the legacy guess-work we
386 * have done in the past
387 */
388 WARN_ON(hw_blocks_count != KBASE_HWCNT_V5_FE_BLOCK_COUNT +
389 KBASE_HWCNT_V5_TILER_BLOCK_COUNT +
390 prfcnt_info->l2_count + shader_core_cnt);
391
392 *phys_layout = (struct kbase_hwcnt_csf_physical_layout){
393 .fe_cnt = KBASE_HWCNT_V5_FE_BLOCK_COUNT,
394 .tiler_cnt = KBASE_HWCNT_V5_TILER_BLOCK_COUNT,
395 .mmu_l2_cnt = prfcnt_info->l2_count,
396 .shader_cnt = shader_core_cnt,
397 .fw_block_cnt = fw_blocks_count,
398 .hw_block_cnt = hw_blocks_count,
399 .block_cnt = fw_blocks_count + hw_blocks_count,
400 .shader_avail_mask = prfcnt_info->core_mask,
401 .headers_per_block = KBASE_HWCNT_V5_HEADERS_PER_BLOCK,
402 .values_per_block = values_per_block,
403 .counters_per_block = values_per_block - KBASE_HWCNT_V5_HEADERS_PER_BLOCK,
404 .enable_mask_offset = KBASE_HWCNT_V5_PRFCNT_EN_HEADER,
405 };
406 }
407
408 static void
kbasep_hwcnt_backend_csf_reset_internal_buffers(struct kbase_hwcnt_backend_csf * backend_csf)409 kbasep_hwcnt_backend_csf_reset_internal_buffers(struct kbase_hwcnt_backend_csf *backend_csf)
410 {
411 size_t user_buf_bytes = backend_csf->info->metadata->dump_buf_bytes;
412
413 memset(backend_csf->to_user_buf, 0, user_buf_bytes);
414 memset(backend_csf->accum_buf, 0, user_buf_bytes);
415 memset(backend_csf->old_sample_buf, 0, backend_csf->info->prfcnt_info.dump_bytes);
416 }
417
418 static void
kbasep_hwcnt_backend_csf_zero_sample_prfcnt_en_header(struct kbase_hwcnt_backend_csf * backend_csf,u32 * sample)419 kbasep_hwcnt_backend_csf_zero_sample_prfcnt_en_header(struct kbase_hwcnt_backend_csf *backend_csf,
420 u32 *sample)
421 {
422 u32 block_idx;
423 const struct kbase_hwcnt_csf_physical_layout *phys_layout;
424 u32 *block_buf;
425
426 phys_layout = &backend_csf->phys_layout;
427
428 for (block_idx = 0; block_idx < phys_layout->block_cnt; block_idx++) {
429 block_buf = sample + block_idx * phys_layout->values_per_block;
430 block_buf[phys_layout->enable_mask_offset] = 0;
431 }
432 }
433
434 static void
kbasep_hwcnt_backend_csf_zero_all_prfcnt_en_header(struct kbase_hwcnt_backend_csf * backend_csf)435 kbasep_hwcnt_backend_csf_zero_all_prfcnt_en_header(struct kbase_hwcnt_backend_csf *backend_csf)
436 {
437 u32 idx;
438 u32 *sample;
439 char *cpu_dump_base;
440 size_t dump_bytes = backend_csf->info->prfcnt_info.dump_bytes;
441
442 cpu_dump_base = (char *)backend_csf->ring_buf_cpu_base;
443
444 for (idx = 0; idx < backend_csf->info->ring_buf_cnt; idx++) {
445 sample = (u32 *)&cpu_dump_base[idx * dump_bytes];
446 kbasep_hwcnt_backend_csf_zero_sample_prfcnt_en_header(backend_csf, sample);
447 }
448 }
449
kbasep_hwcnt_backend_csf_update_user_sample(struct kbase_hwcnt_backend_csf * backend_csf)450 static void kbasep_hwcnt_backend_csf_update_user_sample(struct kbase_hwcnt_backend_csf *backend_csf)
451 {
452 size_t user_buf_bytes = backend_csf->info->metadata->dump_buf_bytes;
453
454 /* Copy the data into the sample and wait for the user to get it. */
455 memcpy(backend_csf->to_user_buf, backend_csf->accum_buf, user_buf_bytes);
456
457 /* After copied data into user sample, clear the accumulator values to
458 * prepare for the next accumulator, such as the next request or
459 * threshold.
460 */
461 memset(backend_csf->accum_buf, 0, user_buf_bytes);
462 }
463
kbasep_hwcnt_backend_csf_accumulate_sample(const struct kbase_hwcnt_csf_physical_layout * phys_layout,size_t dump_bytes,u64 * accum_buf,const u32 * old_sample_buf,const u32 * new_sample_buf,bool clearing_samples)464 static void kbasep_hwcnt_backend_csf_accumulate_sample(
465 const struct kbase_hwcnt_csf_physical_layout *phys_layout, size_t dump_bytes,
466 u64 *accum_buf, const u32 *old_sample_buf, const u32 *new_sample_buf, bool clearing_samples)
467 {
468 size_t block_idx;
469 const u32 *old_block = old_sample_buf;
470 const u32 *new_block = new_sample_buf;
471 u64 *acc_block = accum_buf;
472 const size_t values_per_block = phys_layout->values_per_block;
473
474 /* Performance counter blocks for firmware are stored before blocks for hardware.
475 * We skip over the firmware's performance counter blocks (counters dumping is not
476 * supported for firmware blocks, only hardware ones).
477 */
478 old_block += values_per_block * phys_layout->fw_block_cnt;
479 new_block += values_per_block * phys_layout->fw_block_cnt;
480
481 for (block_idx = phys_layout->fw_block_cnt; block_idx < phys_layout->block_cnt;
482 block_idx++) {
483 const u32 old_enable_mask = old_block[phys_layout->enable_mask_offset];
484 const u32 new_enable_mask = new_block[phys_layout->enable_mask_offset];
485
486 if (new_enable_mask == 0) {
487 /* Hardware block was unavailable or we didn't turn on
488 * any counters. Do nothing.
489 */
490 } else {
491 /* Hardware block was available and it had some counters
492 * enabled. We need to update the accumulation buffer.
493 */
494 size_t ctr_idx;
495
496 /* Unconditionally copy the headers. */
497 for (ctr_idx = 0; ctr_idx < phys_layout->headers_per_block; ctr_idx++) {
498 acc_block[ctr_idx] = new_block[ctr_idx];
499 }
500
501 /* Accumulate counter samples
502 *
503 * When accumulating samples we need to take into
504 * account whether the counter sampling method involves
505 * clearing counters back to zero after each sample is
506 * taken.
507 *
508 * The intention for CSF was that all HW should use
509 * counters which wrap to zero when their maximum value
510 * is reached. This, combined with non-clearing
511 * sampling, enables multiple concurrent users to
512 * request samples without interfering with each other.
513 *
514 * However some early HW may not support wrapping
515 * counters, for these GPUs counters must be cleared on
516 * sample to avoid loss of data due to counters
517 * saturating at their maximum value.
518 */
519 if (!clearing_samples) {
520 if (old_enable_mask == 0) {
521 /* Hardware block was previously
522 * unavailable. Accumulate the new
523 * counters only, as we know previous
524 * values are zeroes.
525 */
526 for (ctr_idx = phys_layout->headers_per_block;
527 ctr_idx < values_per_block; ctr_idx++) {
528 acc_block[ctr_idx] += new_block[ctr_idx];
529 }
530 } else {
531 /* Hardware block was previously
532 * available. Accumulate the delta
533 * between old and new counter values.
534 */
535 for (ctr_idx = phys_layout->headers_per_block;
536 ctr_idx < values_per_block; ctr_idx++) {
537 acc_block[ctr_idx] +=
538 new_block[ctr_idx] - old_block[ctr_idx];
539 }
540 }
541 } else {
542 for (ctr_idx = phys_layout->headers_per_block;
543 ctr_idx < values_per_block; ctr_idx++) {
544 acc_block[ctr_idx] += new_block[ctr_idx];
545 }
546 }
547 }
548 old_block += values_per_block;
549 new_block += values_per_block;
550 acc_block += values_per_block;
551 }
552
553 WARN_ON(old_block != old_sample_buf + (dump_bytes / KBASE_HWCNT_VALUE_HW_BYTES));
554 WARN_ON(new_block != new_sample_buf + (dump_bytes / KBASE_HWCNT_VALUE_HW_BYTES));
555 WARN_ON(acc_block != accum_buf + (dump_bytes / KBASE_HWCNT_VALUE_HW_BYTES) -
556 (values_per_block * phys_layout->fw_block_cnt));
557 (void)dump_bytes;
558 }
559
kbasep_hwcnt_backend_csf_accumulate_samples(struct kbase_hwcnt_backend_csf * backend_csf,u32 extract_index_to_start,u32 insert_index_to_stop)560 static void kbasep_hwcnt_backend_csf_accumulate_samples(struct kbase_hwcnt_backend_csf *backend_csf,
561 u32 extract_index_to_start,
562 u32 insert_index_to_stop)
563 {
564 u32 raw_idx;
565 unsigned long flags = 0UL;
566 u8 *cpu_dump_base = (u8 *)backend_csf->ring_buf_cpu_base;
567 const size_t ring_buf_cnt = backend_csf->info->ring_buf_cnt;
568 const size_t buf_dump_bytes = backend_csf->info->prfcnt_info.dump_bytes;
569 bool clearing_samples = backend_csf->info->prfcnt_info.clearing_samples;
570 u32 *old_sample_buf = backend_csf->old_sample_buf;
571 u32 *new_sample_buf = old_sample_buf;
572
573 if (extract_index_to_start == insert_index_to_stop)
574 /* No samples to accumulate. Early out. */
575 return;
576
577 /* Sync all the buffers to CPU side before read the data. */
578 backend_csf->info->csf_if->ring_buf_sync(backend_csf->info->csf_if->ctx,
579 backend_csf->ring_buf, extract_index_to_start,
580 insert_index_to_stop, true);
581
582 /* Consider u32 wrap case, '!=' is used here instead of '<' operator */
583 for (raw_idx = extract_index_to_start; raw_idx != insert_index_to_stop; raw_idx++) {
584 /* The logical "&" acts as a modulo operation since buf_count
585 * must be a power of two.
586 */
587 const u32 buf_idx = raw_idx & (ring_buf_cnt - 1);
588
589 new_sample_buf = (u32 *)&cpu_dump_base[buf_idx * buf_dump_bytes];
590
591 kbasep_hwcnt_backend_csf_accumulate_sample(&backend_csf->phys_layout,
592 buf_dump_bytes, backend_csf->accum_buf,
593 old_sample_buf, new_sample_buf,
594 clearing_samples);
595
596 old_sample_buf = new_sample_buf;
597 }
598
599 /* Save the newest buffer as the old buffer for next time. */
600 memcpy(backend_csf->old_sample_buf, new_sample_buf, buf_dump_bytes);
601
602 /* Reset the prfcnt_en header on each sample before releasing them. */
603 for (raw_idx = extract_index_to_start; raw_idx != insert_index_to_stop; raw_idx++) {
604 const u32 buf_idx = raw_idx & (ring_buf_cnt - 1);
605 u32 *sample = (u32 *)&cpu_dump_base[buf_idx * buf_dump_bytes];
606
607 kbasep_hwcnt_backend_csf_zero_sample_prfcnt_en_header(backend_csf, sample);
608 }
609
610 /* Sync zeroed buffers to avoid coherency issues on future use. */
611 backend_csf->info->csf_if->ring_buf_sync(backend_csf->info->csf_if->ctx,
612 backend_csf->ring_buf, extract_index_to_start,
613 insert_index_to_stop, false);
614
615 /* After consuming all samples between extract_idx and insert_idx,
616 * set the raw extract index to insert_idx so that the sample buffers
617 * can be released back to the ring buffer pool.
618 */
619 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, &flags);
620 backend_csf->info->csf_if->set_extract_index(backend_csf->info->csf_if->ctx,
621 insert_index_to_stop);
622 /* Update the watchdog last seen index to check any new FW auto samples
623 * in next watchdog callback.
624 */
625 backend_csf->watchdog_last_seen_insert_idx = insert_index_to_stop;
626 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
627 }
628
kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(struct kbase_hwcnt_backend_csf * backend_csf,enum kbase_hwcnt_backend_csf_enable_state new_state)629 static void kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(
630 struct kbase_hwcnt_backend_csf *backend_csf,
631 enum kbase_hwcnt_backend_csf_enable_state new_state)
632 {
633 backend_csf->info->csf_if->assert_lock_held(backend_csf->info->csf_if->ctx);
634
635 if (backend_csf->enable_state != new_state) {
636 backend_csf->enable_state = new_state;
637
638 wake_up(&backend_csf->enable_state_waitq);
639 }
640 }
641
kbasep_hwcnt_backend_watchdog_timer_cb(void * info)642 static void kbasep_hwcnt_backend_watchdog_timer_cb(void *info)
643 {
644 struct kbase_hwcnt_backend_csf_info *csf_info = info;
645 struct kbase_hwcnt_backend_csf *backend_csf;
646 unsigned long flags = 0UL;
647
648 csf_info->csf_if->lock(csf_info->csf_if->ctx, &flags);
649
650 if (WARN_ON(!kbasep_hwcnt_backend_csf_backend_exists(csf_info))) {
651 csf_info->csf_if->unlock(csf_info->csf_if->ctx, flags);
652 return;
653 }
654
655 backend_csf = csf_info->backend;
656
657 /* Only do watchdog request when all conditions are met: */
658 if (/* 1. Backend is enabled. */
659 (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_ENABLED) &&
660 /* 2. FW is not in protected mode. */
661 (!csf_info->fw_in_protected_mode) &&
662 /* 3. dump state indicates no other dumping is in progress. */
663 ((backend_csf->dump_state == KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE) ||
664 (backend_csf->dump_state == KBASE_HWCNT_BACKEND_CSF_DUMP_COMPLETED))) {
665 u32 extract_index = 0U;
666 u32 insert_index = 0U;
667
668 /* Read the raw extract and insert indexes from the CSF interface. */
669 csf_info->csf_if->get_indexes(csf_info->csf_if->ctx, &extract_index, &insert_index);
670
671 /* Do watchdog request if no new FW auto samples. */
672 if (insert_index == backend_csf->watchdog_last_seen_insert_idx) {
673 /* Trigger the watchdog request. */
674 csf_info->csf_if->dump_request(csf_info->csf_if->ctx);
675
676 /* A watchdog dump is required, change the state to
677 * start the request process.
678 */
679 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_WATCHDOG_REQUESTED;
680 }
681 }
682
683 /* Must schedule another callback when in the transitional state because
684 * this function can be called for the first time before the performance
685 * counter enabled interrupt.
686 */
687 if ((backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_ENABLED) ||
688 (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_ENABLED)) {
689 /* Reschedule the timer for next watchdog callback. */
690 csf_info->watchdog_if->modify(csf_info->watchdog_if->timer,
691 HWCNT_BACKEND_WATCHDOG_TIMER_INTERVAL_MS);
692 }
693
694 csf_info->csf_if->unlock(csf_info->csf_if->ctx, flags);
695 }
696
697 /**
698 * kbasep_hwcnt_backend_csf_dump_worker() - HWC dump worker.
699 * @work: Work structure.
700 *
701 * To accumulate all available samples in the ring buffer when a request has
702 * been done.
703 *
704 */
kbasep_hwcnt_backend_csf_dump_worker(struct work_struct * work)705 static void kbasep_hwcnt_backend_csf_dump_worker(struct work_struct *work)
706 {
707 unsigned long flags = 0ULL;
708 struct kbase_hwcnt_backend_csf *backend_csf;
709 u32 insert_index_to_acc;
710 u32 extract_index = 0U;
711 u32 insert_index = 0U;
712
713 WARN_ON(!work);
714 backend_csf = container_of(work, struct kbase_hwcnt_backend_csf, hwc_dump_work);
715 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, &flags);
716 /* Assert the backend is not destroyed. */
717 WARN_ON(backend_csf != backend_csf->info->backend);
718
719 /* The backend was disabled or had an error while the worker was being
720 * launched.
721 */
722 if (backend_csf->enable_state != KBASE_HWCNT_BACKEND_CSF_ENABLED) {
723 WARN_ON(backend_csf->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE);
724 WARN_ON(!completion_done(&backend_csf->dump_completed));
725 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
726 return;
727 }
728
729 WARN_ON(backend_csf->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_WORKER_LAUNCHED);
730
731 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_ACCUMULATING;
732 insert_index_to_acc = backend_csf->insert_index_to_accumulate;
733
734 /* Read the raw extract and insert indexes from the CSF interface. */
735 backend_csf->info->csf_if->get_indexes(backend_csf->info->csf_if->ctx, &extract_index,
736 &insert_index);
737
738 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
739
740 /* Accumulate up to the insert we grabbed at the prfcnt request
741 * interrupt.
742 */
743 kbasep_hwcnt_backend_csf_accumulate_samples(backend_csf, extract_index,
744 insert_index_to_acc);
745
746 /* Copy to the user buffer so if a threshold interrupt fires
747 * between now and get(), the accumulations are untouched.
748 */
749 kbasep_hwcnt_backend_csf_update_user_sample(backend_csf);
750
751 /* Dump done, set state back to COMPLETED for next request. */
752 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, &flags);
753 /* Assert the backend is not destroyed. */
754 WARN_ON(backend_csf != backend_csf->info->backend);
755
756 /* The backend was disabled or had an error while we were accumulating.
757 */
758 if (backend_csf->enable_state != KBASE_HWCNT_BACKEND_CSF_ENABLED) {
759 WARN_ON(backend_csf->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE);
760 WARN_ON(!completion_done(&backend_csf->dump_completed));
761 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
762 return;
763 }
764
765 WARN_ON(backend_csf->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_ACCUMULATING);
766
767 /* Our work here is done - set the wait object and unblock waiters. */
768 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_COMPLETED;
769 complete_all(&backend_csf->dump_completed);
770 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
771 }
772
773 /**
774 * kbasep_hwcnt_backend_csf_threshold_worker() - Threshold worker.
775 *
776 * @work: Work structure.
777 *
778 * Called when a HWC threshold interrupt raised to consume all available samples
779 * in the ring buffer.
780 */
kbasep_hwcnt_backend_csf_threshold_worker(struct work_struct * work)781 static void kbasep_hwcnt_backend_csf_threshold_worker(struct work_struct *work)
782 {
783 unsigned long flags = 0ULL;
784 struct kbase_hwcnt_backend_csf *backend_csf;
785 u32 extract_index = 0U;
786 u32 insert_index = 0U;
787
788 WARN_ON(!work);
789
790 backend_csf = container_of(work, struct kbase_hwcnt_backend_csf, hwc_threshold_work);
791 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, &flags);
792
793 /* Assert the backend is not destroyed. */
794 WARN_ON(backend_csf != backend_csf->info->backend);
795
796 /* Read the raw extract and insert indexes from the CSF interface. */
797 backend_csf->info->csf_if->get_indexes(backend_csf->info->csf_if->ctx, &extract_index,
798 &insert_index);
799
800 /* The backend was disabled or had an error while the worker was being
801 * launched.
802 */
803 if (backend_csf->enable_state != KBASE_HWCNT_BACKEND_CSF_ENABLED) {
804 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
805 return;
806 }
807
808 /* Early out if we are not in the IDLE state or COMPLETED state, as this
809 * means a concurrent dump is in progress and we don't want to
810 * interfere.
811 */
812 if ((backend_csf->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE) &&
813 (backend_csf->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_COMPLETED)) {
814 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
815 return;
816 }
817 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
818
819 /* Accumulate everything we possibly can. We grabbed the insert index
820 * immediately after we acquired the lock but before we checked whether
821 * a concurrent dump was triggered. This ensures that if a concurrent
822 * dump was triggered between releasing the lock and now, we know for a
823 * fact that our insert will not exceed the concurrent dump's
824 * insert_to_accumulate, so we don't risk accumulating too much data.
825 */
826 kbasep_hwcnt_backend_csf_accumulate_samples(backend_csf, extract_index, insert_index);
827
828 /* No need to wake up anything since it is not a user dump request. */
829 }
830
831 static void
kbase_hwcnt_backend_csf_submit_dump_worker(struct kbase_hwcnt_backend_csf_info * csf_info)832 kbase_hwcnt_backend_csf_submit_dump_worker(struct kbase_hwcnt_backend_csf_info *csf_info)
833 {
834 u32 extract_index;
835
836 WARN_ON(!csf_info);
837 csf_info->csf_if->assert_lock_held(csf_info->csf_if->ctx);
838
839 WARN_ON(!kbasep_hwcnt_backend_csf_backend_exists(csf_info));
840 WARN_ON(csf_info->backend->enable_state != KBASE_HWCNT_BACKEND_CSF_ENABLED);
841 WARN_ON(csf_info->backend->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_QUERYING_INSERT);
842
843 /* Save insert index now so that the dump worker only accumulates the
844 * HWC data associated with this request. Extract index is not stored
845 * as that needs to be checked when accumulating to prevent re-reading
846 * buffers that have already been read and returned to the GPU.
847 */
848 csf_info->csf_if->get_indexes(csf_info->csf_if->ctx, &extract_index,
849 &csf_info->backend->insert_index_to_accumulate);
850 csf_info->backend->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_WORKER_LAUNCHED;
851
852 /* Submit the accumulator task into the work queue. */
853 queue_work(csf_info->backend->hwc_dump_workq, &csf_info->backend->hwc_dump_work);
854 }
855
856 static void
kbasep_hwcnt_backend_csf_get_physical_enable(struct kbase_hwcnt_backend_csf * backend_csf,const struct kbase_hwcnt_enable_map * enable_map,struct kbase_hwcnt_backend_csf_if_enable * enable)857 kbasep_hwcnt_backend_csf_get_physical_enable(struct kbase_hwcnt_backend_csf *backend_csf,
858 const struct kbase_hwcnt_enable_map *enable_map,
859 struct kbase_hwcnt_backend_csf_if_enable *enable)
860 {
861 enum kbase_hwcnt_physical_set phys_counter_set;
862 struct kbase_hwcnt_physical_enable_map phys_enable_map;
863
864 kbase_hwcnt_gpu_enable_map_to_physical(&phys_enable_map, enable_map);
865
866 /* process the enable_map to guarantee the block header is enabled which
867 * is needed for delta calculation.
868 */
869 kbasep_hwcnt_backend_csf_process_enable_map(&phys_enable_map);
870
871 kbase_hwcnt_gpu_set_to_physical(&phys_counter_set, backend_csf->info->counter_set);
872
873 /* Use processed enable_map to enable HWC in HW level. */
874 enable->fe_bm = phys_enable_map.fe_bm;
875 enable->shader_bm = phys_enable_map.shader_bm;
876 enable->tiler_bm = phys_enable_map.tiler_bm;
877 enable->mmu_l2_bm = phys_enable_map.mmu_l2_bm;
878 enable->counter_set = phys_counter_set;
879 enable->clk_enable_map = enable_map->clk_enable_map;
880 }
881
882 /* CSF backend implementation of kbase_hwcnt_backend_dump_enable_nolock_fn */
883 static int
kbasep_hwcnt_backend_csf_dump_enable_nolock(struct kbase_hwcnt_backend * backend,const struct kbase_hwcnt_enable_map * enable_map)884 kbasep_hwcnt_backend_csf_dump_enable_nolock(struct kbase_hwcnt_backend *backend,
885 const struct kbase_hwcnt_enable_map *enable_map)
886 {
887 struct kbase_hwcnt_backend_csf *backend_csf = (struct kbase_hwcnt_backend_csf *)backend;
888 struct kbase_hwcnt_backend_csf_if_enable enable;
889 int err;
890
891 if (!backend_csf || !enable_map || (enable_map->metadata != backend_csf->info->metadata))
892 return -EINVAL;
893
894 backend_csf->info->csf_if->assert_lock_held(backend_csf->info->csf_if->ctx);
895
896 kbasep_hwcnt_backend_csf_get_physical_enable(backend_csf, enable_map, &enable);
897
898 /* enable_state should be DISABLED before we transfer it to enabled */
899 if (backend_csf->enable_state != KBASE_HWCNT_BACKEND_CSF_DISABLED)
900 return -EIO;
901
902 err = backend_csf->info->watchdog_if->enable(backend_csf->info->watchdog_if->timer,
903 HWCNT_BACKEND_WATCHDOG_TIMER_INTERVAL_MS,
904 kbasep_hwcnt_backend_watchdog_timer_cb,
905 backend_csf->info);
906 if (err)
907 return err;
908
909 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE;
910 WARN_ON(!completion_done(&backend_csf->dump_completed));
911 kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(
912 backend_csf, KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_ENABLED);
913
914 backend_csf->info->csf_if->dump_enable(backend_csf->info->csf_if->ctx,
915 backend_csf->ring_buf, &enable);
916
917 kbasep_hwcnt_backend_csf_cc_initial_sample(backend_csf, enable_map);
918
919 return 0;
920 }
921
922 /* CSF backend implementation of kbase_hwcnt_backend_dump_enable_fn */
kbasep_hwcnt_backend_csf_dump_enable(struct kbase_hwcnt_backend * backend,const struct kbase_hwcnt_enable_map * enable_map)923 static int kbasep_hwcnt_backend_csf_dump_enable(struct kbase_hwcnt_backend *backend,
924 const struct kbase_hwcnt_enable_map *enable_map)
925 {
926 int errcode;
927 unsigned long flags = 0UL;
928 struct kbase_hwcnt_backend_csf *backend_csf = (struct kbase_hwcnt_backend_csf *)backend;
929
930 if (!backend_csf)
931 return -EINVAL;
932
933 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, &flags);
934 errcode = kbasep_hwcnt_backend_csf_dump_enable_nolock(backend, enable_map);
935 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
936 return errcode;
937 }
938
kbasep_hwcnt_backend_csf_wait_enable_transition_complete(struct kbase_hwcnt_backend_csf * backend_csf,unsigned long * lock_flags)939 static void kbasep_hwcnt_backend_csf_wait_enable_transition_complete(
940 struct kbase_hwcnt_backend_csf *backend_csf, unsigned long *lock_flags)
941 {
942 backend_csf->info->csf_if->assert_lock_held(backend_csf->info->csf_if->ctx);
943
944 while ((backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_ENABLED) ||
945 (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_DISABLED)) {
946 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, *lock_flags);
947
948 wait_event(backend_csf->enable_state_waitq,
949 (backend_csf->enable_state !=
950 KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_ENABLED) &&
951 (backend_csf->enable_state !=
952 KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_DISABLED));
953
954 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, lock_flags);
955 }
956 }
957
958 /* CSF backend implementation of kbase_hwcnt_backend_dump_disable_fn */
kbasep_hwcnt_backend_csf_dump_disable(struct kbase_hwcnt_backend * backend)959 static void kbasep_hwcnt_backend_csf_dump_disable(struct kbase_hwcnt_backend *backend)
960 {
961 unsigned long flags = 0UL;
962 struct kbase_hwcnt_backend_csf *backend_csf = (struct kbase_hwcnt_backend_csf *)backend;
963 bool do_disable = false;
964
965 WARN_ON(!backend_csf);
966
967 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, &flags);
968
969 /* Make sure we wait until any previous enable or disable have completed
970 * before doing anything.
971 */
972 kbasep_hwcnt_backend_csf_wait_enable_transition_complete(backend_csf, &flags);
973
974 if (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_DISABLED ||
975 backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR) {
976 /* If we are already disabled or in an unrecoverable error
977 * state, there is nothing for us to do.
978 */
979 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
980 return;
981 }
982
983 if (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_ENABLED) {
984 kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(
985 backend_csf, KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_DISABLED);
986 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE;
987 complete_all(&backend_csf->dump_completed);
988 /* Only disable if we were previously enabled - in all other
989 * cases the call to disable will have already been made.
990 */
991 do_disable = true;
992 }
993
994 WARN_ON(backend_csf->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE);
995 WARN_ON(!completion_done(&backend_csf->dump_completed));
996
997 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
998
999 /* Deregister the timer and block until any timer callback has completed.
1000 * We've transitioned out of the ENABLED state so we can guarantee it
1001 * won't reschedule itself.
1002 */
1003 backend_csf->info->watchdog_if->disable(backend_csf->info->watchdog_if->timer);
1004
1005 /* Block until any async work has completed. We have transitioned out of
1006 * the ENABLED state so we can guarantee no new work will concurrently
1007 * be submitted.
1008 */
1009 flush_workqueue(backend_csf->hwc_dump_workq);
1010
1011 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, &flags);
1012
1013 if (do_disable)
1014 backend_csf->info->csf_if->dump_disable(backend_csf->info->csf_if->ctx);
1015
1016 kbasep_hwcnt_backend_csf_wait_enable_transition_complete(backend_csf, &flags);
1017
1018 switch (backend_csf->enable_state) {
1019 case KBASE_HWCNT_BACKEND_CSF_DISABLED_WAIT_FOR_WORKER:
1020 kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(
1021 backend_csf, KBASE_HWCNT_BACKEND_CSF_DISABLED);
1022 break;
1023 case KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR_WAIT_FOR_WORKER:
1024 kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(
1025 backend_csf, KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR);
1026 break;
1027 default:
1028 WARN_ON(true);
1029 break;
1030 }
1031
1032 backend_csf->user_requested = false;
1033 backend_csf->watchdog_last_seen_insert_idx = 0;
1034
1035 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
1036
1037 /* After disable, zero the header of all buffers in the ring buffer back
1038 * to 0 to prepare for the next enable.
1039 */
1040 kbasep_hwcnt_backend_csf_zero_all_prfcnt_en_header(backend_csf);
1041
1042 /* Sync zeroed buffers to avoid coherency issues on future use. */
1043 backend_csf->info->csf_if->ring_buf_sync(backend_csf->info->csf_if->ctx,
1044 backend_csf->ring_buf, 0,
1045 backend_csf->info->ring_buf_cnt, false);
1046
1047 /* Reset accumulator, old_sample_buf and user_sample to all-0 to prepare
1048 * for next enable.
1049 */
1050 kbasep_hwcnt_backend_csf_reset_internal_buffers(backend_csf);
1051 }
1052
1053 /* CSF backend implementation of kbase_hwcnt_backend_dump_request_fn */
kbasep_hwcnt_backend_csf_dump_request(struct kbase_hwcnt_backend * backend,u64 * dump_time_ns)1054 static int kbasep_hwcnt_backend_csf_dump_request(struct kbase_hwcnt_backend *backend,
1055 u64 *dump_time_ns)
1056 {
1057 unsigned long flags = 0UL;
1058 struct kbase_hwcnt_backend_csf *backend_csf = (struct kbase_hwcnt_backend_csf *)backend;
1059 bool do_request = false;
1060 bool watchdog_dumping = false;
1061
1062 if (!backend_csf)
1063 return -EINVAL;
1064
1065 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, &flags);
1066
1067 /* If we're transitioning to enabled there's nothing to accumulate, and
1068 * the user dump buffer is already zeroed. We can just short circuit to
1069 * the DUMP_COMPLETED state.
1070 */
1071 if (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_ENABLED) {
1072 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_COMPLETED;
1073 *dump_time_ns = kbasep_hwcnt_backend_csf_timestamp_ns(backend);
1074 kbasep_hwcnt_backend_csf_cc_update(backend_csf);
1075 backend_csf->user_requested = true;
1076 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
1077 return 0;
1078 }
1079
1080 /* Otherwise, make sure we're already enabled. */
1081 if (backend_csf->enable_state != KBASE_HWCNT_BACKEND_CSF_ENABLED) {
1082 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
1083 return -EIO;
1084 }
1085
1086 /* Make sure that this is either the first request since enable or the
1087 * previous user dump has completed or a watchdog dump is in progress,
1088 * so we can avoid midway through a user dump.
1089 * If user request comes while a watchdog dumping is in progress,
1090 * the user request takes the ownership of the watchdog dumping sample by
1091 * changing the dump_state so the interrupt for the watchdog
1092 * request can be processed instead of ignored.
1093 */
1094 if ((backend_csf->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE) &&
1095 (backend_csf->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_COMPLETED) &&
1096 (backend_csf->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_WATCHDOG_REQUESTED)) {
1097 /* HWC is disabled or another user dump is ongoing,
1098 * or we're on fault.
1099 */
1100 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
1101 /* HWC is disabled or another dump is ongoing, or we are on
1102 * fault.
1103 */
1104 return -EIO;
1105 }
1106
1107 /* Reset the completion so dump_wait() has something to wait on. */
1108 reinit_completion(&backend_csf->dump_completed);
1109
1110 if (backend_csf->dump_state == KBASE_HWCNT_BACKEND_CSF_DUMP_WATCHDOG_REQUESTED)
1111 watchdog_dumping = true;
1112
1113 if ((backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_ENABLED) &&
1114 !backend_csf->info->fw_in_protected_mode) {
1115 /* Only do the request if we are fully enabled and not in
1116 * protected mode.
1117 */
1118 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_REQUESTED;
1119 do_request = true;
1120 } else {
1121 /* Skip the request and waiting for ack and go straight to
1122 * checking the insert and kicking off the worker to do the dump
1123 */
1124 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_QUERYING_INSERT;
1125 }
1126
1127 /* CSF firmware might enter protected mode now, but still call request.
1128 * That is fine, as we changed state while holding the lock, so the
1129 * protected mode enter function will query the insert and launch the
1130 * dumping worker.
1131 * At some point we will get the dump request ACK saying a dump is done,
1132 * but we can ignore it if we are not in the REQUESTED state and process
1133 * it in next round dumping worker.
1134 */
1135
1136 *dump_time_ns = kbasep_hwcnt_backend_csf_timestamp_ns(backend);
1137 kbasep_hwcnt_backend_csf_cc_update(backend_csf);
1138 backend_csf->user_requested = true;
1139
1140 if (do_request) {
1141 /* If a watchdog dumping is in progress, don't need to do
1142 * another request, just update the dump_state and take the
1143 * ownership of the sample which watchdog requested.
1144 */
1145 if (!watchdog_dumping)
1146 backend_csf->info->csf_if->dump_request(backend_csf->info->csf_if->ctx);
1147 } else
1148 kbase_hwcnt_backend_csf_submit_dump_worker(backend_csf->info);
1149
1150 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
1151
1152 /* Modify watchdog timer to delay the regular check time since
1153 * just requested.
1154 */
1155 backend_csf->info->watchdog_if->modify(backend_csf->info->watchdog_if->timer,
1156 HWCNT_BACKEND_WATCHDOG_TIMER_INTERVAL_MS);
1157
1158 return 0;
1159 }
1160
1161 /* CSF backend implementation of kbase_hwcnt_backend_dump_wait_fn */
kbasep_hwcnt_backend_csf_dump_wait(struct kbase_hwcnt_backend * backend)1162 static int kbasep_hwcnt_backend_csf_dump_wait(struct kbase_hwcnt_backend *backend)
1163 {
1164 unsigned long flags = 0UL;
1165 struct kbase_hwcnt_backend_csf *backend_csf = (struct kbase_hwcnt_backend_csf *)backend;
1166 int errcode;
1167
1168 if (!backend_csf)
1169 return -EINVAL;
1170
1171 wait_for_completion(&backend_csf->dump_completed);
1172
1173 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, &flags);
1174 /* Make sure the last dump actually succeeded when user requested is
1175 * set.
1176 */
1177 if (backend_csf->user_requested &&
1178 ((backend_csf->dump_state == KBASE_HWCNT_BACKEND_CSF_DUMP_COMPLETED) ||
1179 (backend_csf->dump_state == KBASE_HWCNT_BACKEND_CSF_DUMP_WATCHDOG_REQUESTED)))
1180 errcode = 0;
1181 else
1182 errcode = -EIO;
1183
1184 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
1185
1186 return errcode;
1187 }
1188
1189 /* CSF backend implementation of kbase_hwcnt_backend_dump_clear_fn */
kbasep_hwcnt_backend_csf_dump_clear(struct kbase_hwcnt_backend * backend)1190 static int kbasep_hwcnt_backend_csf_dump_clear(struct kbase_hwcnt_backend *backend)
1191 {
1192 struct kbase_hwcnt_backend_csf *backend_csf = (struct kbase_hwcnt_backend_csf *)backend;
1193 int errcode;
1194 u64 ts;
1195
1196 if (!backend_csf)
1197 return -EINVAL;
1198
1199 /* Request a dump so we can clear all current counters. */
1200 errcode = kbasep_hwcnt_backend_csf_dump_request(backend, &ts);
1201 if (!errcode)
1202 /* Wait for the manual dump or auto dump to be done and
1203 * accumulator to be updated.
1204 */
1205 errcode = kbasep_hwcnt_backend_csf_dump_wait(backend);
1206
1207 return errcode;
1208 }
1209
1210 /* CSF backend implementation of kbase_hwcnt_backend_dump_get_fn */
kbasep_hwcnt_backend_csf_dump_get(struct kbase_hwcnt_backend * backend,struct kbase_hwcnt_dump_buffer * dst,const struct kbase_hwcnt_enable_map * dst_enable_map,bool accumulate)1211 static int kbasep_hwcnt_backend_csf_dump_get(struct kbase_hwcnt_backend *backend,
1212 struct kbase_hwcnt_dump_buffer *dst,
1213 const struct kbase_hwcnt_enable_map *dst_enable_map,
1214 bool accumulate)
1215 {
1216 struct kbase_hwcnt_backend_csf *backend_csf = (struct kbase_hwcnt_backend_csf *)backend;
1217 int ret;
1218 size_t clk;
1219
1220 if (!backend_csf || !dst || !dst_enable_map ||
1221 (backend_csf->info->metadata != dst->metadata) ||
1222 (dst_enable_map->metadata != dst->metadata))
1223 return -EINVAL;
1224
1225 /* Extract elapsed cycle count for each clock domain if enabled. */
1226 kbase_hwcnt_metadata_for_each_clock(dst_enable_map->metadata, clk)
1227 {
1228 if (!kbase_hwcnt_clk_enable_map_enabled(dst_enable_map->clk_enable_map, clk))
1229 continue;
1230
1231 /* Reset the counter to zero if accumulation is off. */
1232 if (!accumulate)
1233 dst->clk_cnt_buf[clk] = 0;
1234 dst->clk_cnt_buf[clk] += backend_csf->cycle_count_elapsed[clk];
1235 }
1236
1237 /* We just return the user buffer without checking the current state,
1238 * as it is undefined to call this function without a prior succeeding
1239 * one to dump_wait().
1240 */
1241 ret = kbase_hwcnt_csf_dump_get(dst, backend_csf->to_user_buf, dst_enable_map, accumulate);
1242
1243 return ret;
1244 }
1245
1246 /**
1247 * kbasep_hwcnt_backend_csf_destroy() - Destroy CSF backend.
1248 * @backend_csf: Pointer to CSF backend to destroy.
1249 *
1250 * Can be safely called on a backend in any state of partial construction.
1251 *
1252 */
kbasep_hwcnt_backend_csf_destroy(struct kbase_hwcnt_backend_csf * backend_csf)1253 static void kbasep_hwcnt_backend_csf_destroy(struct kbase_hwcnt_backend_csf *backend_csf)
1254 {
1255 if (!backend_csf)
1256 return;
1257
1258 destroy_workqueue(backend_csf->hwc_dump_workq);
1259
1260 backend_csf->info->csf_if->ring_buf_free(backend_csf->info->csf_if->ctx,
1261 backend_csf->ring_buf);
1262
1263 kfree(backend_csf->accum_buf);
1264 backend_csf->accum_buf = NULL;
1265
1266 kfree(backend_csf->old_sample_buf);
1267 backend_csf->old_sample_buf = NULL;
1268
1269 kfree(backend_csf->to_user_buf);
1270 backend_csf->to_user_buf = NULL;
1271
1272 kfree(backend_csf);
1273 }
1274
1275 /**
1276 * kbasep_hwcnt_backend_csf_create() - Create a CSF backend instance.
1277 *
1278 * @csf_info: Non-NULL pointer to backend info.
1279 * @out_backend: Non-NULL pointer to where backend is stored on success.
1280 *
1281 * Return: 0 on success, else error code.
1282 */
kbasep_hwcnt_backend_csf_create(struct kbase_hwcnt_backend_csf_info * csf_info,struct kbase_hwcnt_backend_csf ** out_backend)1283 static int kbasep_hwcnt_backend_csf_create(struct kbase_hwcnt_backend_csf_info *csf_info,
1284 struct kbase_hwcnt_backend_csf **out_backend)
1285 {
1286 struct kbase_hwcnt_backend_csf *backend_csf = NULL;
1287 int errcode = -ENOMEM;
1288
1289 WARN_ON(!csf_info);
1290 WARN_ON(!out_backend);
1291
1292 backend_csf = kzalloc(sizeof(*backend_csf), GFP_KERNEL);
1293 if (!backend_csf)
1294 goto alloc_error;
1295
1296 backend_csf->info = csf_info;
1297 kbasep_hwcnt_backend_csf_init_layout(&csf_info->prfcnt_info, &backend_csf->phys_layout);
1298
1299 backend_csf->accum_buf = kzalloc(csf_info->metadata->dump_buf_bytes, GFP_KERNEL);
1300 if (!backend_csf->accum_buf)
1301 goto err_alloc_acc_buf;
1302
1303 backend_csf->old_sample_buf = kzalloc(csf_info->prfcnt_info.dump_bytes, GFP_KERNEL);
1304 if (!backend_csf->old_sample_buf)
1305 goto err_alloc_pre_sample_buf;
1306
1307 backend_csf->to_user_buf = kzalloc(csf_info->metadata->dump_buf_bytes, GFP_KERNEL);
1308 if (!backend_csf->to_user_buf)
1309 goto err_alloc_user_sample_buf;
1310
1311 errcode = csf_info->csf_if->ring_buf_alloc(csf_info->csf_if->ctx, csf_info->ring_buf_cnt,
1312 &backend_csf->ring_buf_cpu_base,
1313 &backend_csf->ring_buf);
1314 if (errcode)
1315 goto err_ring_buf_alloc;
1316 errcode = -ENOMEM;
1317
1318 /* Zero all performance enable header to prepare for first enable. */
1319 kbasep_hwcnt_backend_csf_zero_all_prfcnt_en_header(backend_csf);
1320
1321 /* Sync zeroed buffers to avoid coherency issues on use. */
1322 backend_csf->info->csf_if->ring_buf_sync(backend_csf->info->csf_if->ctx,
1323 backend_csf->ring_buf, 0,
1324 backend_csf->info->ring_buf_cnt, false);
1325
1326 init_completion(&backend_csf->dump_completed);
1327
1328 init_waitqueue_head(&backend_csf->enable_state_waitq);
1329
1330 /* Allocate a single threaded work queue for dump worker and threshold
1331 * worker.
1332 */
1333 backend_csf->hwc_dump_workq =
1334 alloc_workqueue("mali_hwc_dump_wq", WQ_HIGHPRI | WQ_UNBOUND, 1);
1335 if (!backend_csf->hwc_dump_workq)
1336 goto err_alloc_workqueue;
1337
1338 INIT_WORK(&backend_csf->hwc_dump_work, kbasep_hwcnt_backend_csf_dump_worker);
1339 INIT_WORK(&backend_csf->hwc_threshold_work, kbasep_hwcnt_backend_csf_threshold_worker);
1340
1341 backend_csf->enable_state = KBASE_HWCNT_BACKEND_CSF_DISABLED;
1342 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE;
1343 complete_all(&backend_csf->dump_completed);
1344 backend_csf->user_requested = false;
1345 backend_csf->watchdog_last_seen_insert_idx = 0;
1346
1347 *out_backend = backend_csf;
1348 return 0;
1349
1350 err_alloc_workqueue:
1351 backend_csf->info->csf_if->ring_buf_free(backend_csf->info->csf_if->ctx,
1352 backend_csf->ring_buf);
1353 err_ring_buf_alloc:
1354 kfree(backend_csf->to_user_buf);
1355 backend_csf->to_user_buf = NULL;
1356 err_alloc_user_sample_buf:
1357 kfree(backend_csf->old_sample_buf);
1358 backend_csf->old_sample_buf = NULL;
1359 err_alloc_pre_sample_buf:
1360 kfree(backend_csf->accum_buf);
1361 backend_csf->accum_buf = NULL;
1362 err_alloc_acc_buf:
1363 kfree(backend_csf);
1364 alloc_error:
1365 return errcode;
1366 }
1367
1368 /* CSF backend implementation of kbase_hwcnt_backend_init_fn */
kbasep_hwcnt_backend_csf_init(const struct kbase_hwcnt_backend_info * info,struct kbase_hwcnt_backend ** out_backend)1369 static int kbasep_hwcnt_backend_csf_init(const struct kbase_hwcnt_backend_info *info,
1370 struct kbase_hwcnt_backend **out_backend)
1371 {
1372 unsigned long flags = 0UL;
1373 struct kbase_hwcnt_backend_csf *backend_csf = NULL;
1374 struct kbase_hwcnt_backend_csf_info *csf_info = (struct kbase_hwcnt_backend_csf_info *)info;
1375 int errcode;
1376 bool success = false;
1377
1378 if (!info || !out_backend)
1379 return -EINVAL;
1380
1381 /* Create the backend. */
1382 errcode = kbasep_hwcnt_backend_csf_create(csf_info, &backend_csf);
1383 if (errcode)
1384 return errcode;
1385
1386 /* If it was not created before, attach it to csf_info.
1387 * Use spin lock to avoid concurrent initialization.
1388 */
1389 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, &flags);
1390 if (csf_info->backend == NULL) {
1391 csf_info->backend = backend_csf;
1392 *out_backend = (struct kbase_hwcnt_backend *)backend_csf;
1393 success = true;
1394 if (csf_info->unrecoverable_error_happened)
1395 backend_csf->enable_state = KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR;
1396 }
1397 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
1398
1399 /* Destroy the new created backend if the backend has already created
1400 * before. In normal case, this won't happen if the client call init()
1401 * function properly.
1402 */
1403 if (!success) {
1404 kbasep_hwcnt_backend_csf_destroy(backend_csf);
1405 return -EBUSY;
1406 }
1407
1408 return 0;
1409 }
1410
1411 /* CSF backend implementation of kbase_hwcnt_backend_term_fn */
kbasep_hwcnt_backend_csf_term(struct kbase_hwcnt_backend * backend)1412 static void kbasep_hwcnt_backend_csf_term(struct kbase_hwcnt_backend *backend)
1413 {
1414 unsigned long flags = 0UL;
1415 struct kbase_hwcnt_backend_csf *backend_csf = (struct kbase_hwcnt_backend_csf *)backend;
1416
1417 if (!backend)
1418 return;
1419
1420 kbasep_hwcnt_backend_csf_dump_disable(backend);
1421
1422 /* Set the backend in csf_info to NULL so we won't handle any external
1423 * notification anymore since we are terminating.
1424 */
1425 backend_csf->info->csf_if->lock(backend_csf->info->csf_if->ctx, &flags);
1426 backend_csf->info->backend = NULL;
1427 backend_csf->info->csf_if->unlock(backend_csf->info->csf_if->ctx, flags);
1428
1429 kbasep_hwcnt_backend_csf_destroy(backend_csf);
1430 }
1431
1432 /**
1433 * kbasep_hwcnt_backend_csf_info_destroy() - Destroy a CSF backend info.
1434 * @info: Pointer to info to destroy.
1435 *
1436 * Can be safely called on a backend info in any state of partial construction.
1437 *
1438 */
kbasep_hwcnt_backend_csf_info_destroy(const struct kbase_hwcnt_backend_csf_info * info)1439 static void kbasep_hwcnt_backend_csf_info_destroy(const struct kbase_hwcnt_backend_csf_info *info)
1440 {
1441 if (!info)
1442 return;
1443
1444 /* The backend should be destroyed before the info object destroy. */
1445 WARN_ON(info->backend != NULL);
1446
1447 /* The metadata should be destroyed before the info object destroy. */
1448 WARN_ON(info->metadata != NULL);
1449
1450 kfree(info);
1451 }
1452
1453 /**
1454 * kbasep_hwcnt_backend_csf_info_create() - Create a CSF backend info.
1455 *
1456 * @csf_if: Non-NULL pointer to a hwcnt backend CSF interface structure
1457 * used to create backend interface.
1458 * @ring_buf_cnt: The buffer count of the CSF hwcnt backend ring buffer.
1459 * MUST be power of 2.
1460 * @watchdog_if: Non-NULL pointer to a hwcnt watchdog interface structure used to create
1461 * backend interface.
1462 * @out_info: Non-NULL pointer to where info is stored on success.
1463 *
1464 * Return: 0 on success, else error code.
1465 */
1466 static int
kbasep_hwcnt_backend_csf_info_create(struct kbase_hwcnt_backend_csf_if * csf_if,u32 ring_buf_cnt,struct kbase_hwcnt_watchdog_interface * watchdog_if,const struct kbase_hwcnt_backend_csf_info ** out_info)1467 kbasep_hwcnt_backend_csf_info_create(struct kbase_hwcnt_backend_csf_if *csf_if, u32 ring_buf_cnt,
1468 struct kbase_hwcnt_watchdog_interface *watchdog_if,
1469 const struct kbase_hwcnt_backend_csf_info **out_info)
1470 {
1471 struct kbase_hwcnt_backend_csf_info *info = NULL;
1472
1473 if (WARN_ON(!csf_if) || WARN_ON(!watchdog_if) || WARN_ON(!out_info) ||
1474 WARN_ON(!is_power_of_2(ring_buf_cnt)))
1475 return -EINVAL;
1476
1477 info = kmalloc(sizeof(*info), GFP_KERNEL);
1478 if (!info)
1479 return -ENOMEM;
1480
1481 *info = (struct kbase_hwcnt_backend_csf_info)
1482 {
1483 #if defined(CONFIG_MALI_BIFROST_PRFCNT_SET_SECONDARY)
1484 .counter_set = KBASE_HWCNT_SET_SECONDARY,
1485 #elif defined(CONFIG_MALI_PRFCNT_SET_TERTIARY)
1486 .counter_set = KBASE_HWCNT_SET_TERTIARY,
1487 #else
1488 /* Default to primary */
1489 .counter_set = KBASE_HWCNT_SET_PRIMARY,
1490 #endif
1491 .backend = NULL, .csf_if = csf_if, .ring_buf_cnt = ring_buf_cnt,
1492 .fw_in_protected_mode = false, .unrecoverable_error_happened = false,
1493 .watchdog_if = watchdog_if,
1494 };
1495 *out_info = info;
1496
1497 return 0;
1498 }
1499
1500 /* CSF backend implementation of kbase_hwcnt_backend_metadata_fn */
1501 static const struct kbase_hwcnt_metadata *
kbasep_hwcnt_backend_csf_metadata(const struct kbase_hwcnt_backend_info * info)1502 kbasep_hwcnt_backend_csf_metadata(const struct kbase_hwcnt_backend_info *info)
1503 {
1504 if (!info)
1505 return NULL;
1506
1507 WARN_ON(!((const struct kbase_hwcnt_backend_csf_info *)info)->metadata);
1508
1509 return ((const struct kbase_hwcnt_backend_csf_info *)info)->metadata;
1510 }
1511
1512 static void
kbasep_hwcnt_backend_csf_handle_unrecoverable_error(struct kbase_hwcnt_backend_csf * backend_csf)1513 kbasep_hwcnt_backend_csf_handle_unrecoverable_error(struct kbase_hwcnt_backend_csf *backend_csf)
1514 {
1515 bool do_disable = false;
1516
1517 backend_csf->info->csf_if->assert_lock_held(backend_csf->info->csf_if->ctx);
1518
1519 /* We are already in or transitioning to the unrecoverable error state.
1520 * Early out.
1521 */
1522 if ((backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR) ||
1523 (backend_csf->enable_state ==
1524 KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR_WAIT_FOR_WORKER))
1525 return;
1526
1527 /* If we are disabled, we know we have no pending workers, so skip the
1528 * waiting state.
1529 */
1530 if (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_DISABLED) {
1531 kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(
1532 backend_csf, KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR);
1533 return;
1534 }
1535
1536 /* Trigger a disable only if we are not already transitioning to
1537 * disabled, we don't want to disable twice if an unrecoverable error
1538 * happens while we are disabling.
1539 */
1540 do_disable =
1541 (backend_csf->enable_state != KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_DISABLED);
1542
1543 kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(
1544 backend_csf, KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR_WAIT_FOR_WORKER);
1545
1546 /* Transition the dump to the IDLE state and unblock any waiters. The
1547 * IDLE state signifies an error.
1548 */
1549 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE;
1550 complete_all(&backend_csf->dump_completed);
1551
1552 /* Trigger a disable only if we are not already transitioning to
1553 * disabled, - we don't want to disable twice if an unrecoverable error
1554 * happens while we are disabling.
1555 */
1556 if (do_disable)
1557 backend_csf->info->csf_if->dump_disable(backend_csf->info->csf_if->ctx);
1558 }
1559
1560 static void
kbasep_hwcnt_backend_csf_handle_recoverable_error(struct kbase_hwcnt_backend_csf * backend_csf)1561 kbasep_hwcnt_backend_csf_handle_recoverable_error(struct kbase_hwcnt_backend_csf *backend_csf)
1562 {
1563 backend_csf->info->csf_if->assert_lock_held(backend_csf->info->csf_if->ctx);
1564
1565 switch (backend_csf->enable_state) {
1566 case KBASE_HWCNT_BACKEND_CSF_DISABLED:
1567 case KBASE_HWCNT_BACKEND_CSF_DISABLED_WAIT_FOR_WORKER:
1568 case KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_DISABLED:
1569 case KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR:
1570 case KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR_WAIT_FOR_WORKER:
1571 /* Already disabled or disabling, or in an unrecoverable error.
1572 * Nothing to be done to handle the error.
1573 */
1574 return;
1575 case KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_ENABLED:
1576 /* A seemingly recoverable error that occurs while we are
1577 * transitioning to enabled is probably unrecoverable.
1578 */
1579 kbasep_hwcnt_backend_csf_handle_unrecoverable_error(backend_csf);
1580 return;
1581 case KBASE_HWCNT_BACKEND_CSF_ENABLED:
1582 /* Start transitioning to the disabled state. We can't wait for
1583 * it as this recoverable error might be triggered from an
1584 * interrupt. The wait will be done in the eventual call to
1585 * disable().
1586 */
1587 kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(
1588 backend_csf, KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_DISABLED);
1589 /* Transition the dump to the IDLE state and unblock any
1590 * waiters. The IDLE state signifies an error.
1591 */
1592 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_IDLE;
1593 complete_all(&backend_csf->dump_completed);
1594
1595 backend_csf->info->csf_if->dump_disable(backend_csf->info->csf_if->ctx);
1596 return;
1597 }
1598 }
1599
kbase_hwcnt_backend_csf_protm_entered(struct kbase_hwcnt_backend_interface * iface)1600 void kbase_hwcnt_backend_csf_protm_entered(struct kbase_hwcnt_backend_interface *iface)
1601 {
1602 struct kbase_hwcnt_backend_csf_info *csf_info =
1603 (struct kbase_hwcnt_backend_csf_info *)iface->info;
1604
1605 csf_info->csf_if->assert_lock_held(csf_info->csf_if->ctx);
1606 csf_info->fw_in_protected_mode = true;
1607
1608 /* Call on_prfcnt_sample() to trigger collection of the protected mode
1609 * entry auto-sample if there is currently a pending dump request.
1610 */
1611 kbase_hwcnt_backend_csf_on_prfcnt_sample(iface);
1612 }
1613
kbase_hwcnt_backend_csf_protm_exited(struct kbase_hwcnt_backend_interface * iface)1614 void kbase_hwcnt_backend_csf_protm_exited(struct kbase_hwcnt_backend_interface *iface)
1615 {
1616 struct kbase_hwcnt_backend_csf_info *csf_info;
1617
1618 csf_info = (struct kbase_hwcnt_backend_csf_info *)iface->info;
1619
1620 csf_info->csf_if->assert_lock_held(csf_info->csf_if->ctx);
1621 csf_info->fw_in_protected_mode = false;
1622 }
1623
kbase_hwcnt_backend_csf_on_unrecoverable_error(struct kbase_hwcnt_backend_interface * iface)1624 void kbase_hwcnt_backend_csf_on_unrecoverable_error(struct kbase_hwcnt_backend_interface *iface)
1625 {
1626 unsigned long flags = 0UL;
1627 struct kbase_hwcnt_backend_csf_info *csf_info;
1628
1629 csf_info = (struct kbase_hwcnt_backend_csf_info *)iface->info;
1630
1631 csf_info->csf_if->lock(csf_info->csf_if->ctx, &flags);
1632 csf_info->unrecoverable_error_happened = true;
1633 /* Early out if the backend does not exist. */
1634 if (!kbasep_hwcnt_backend_csf_backend_exists(csf_info)) {
1635 csf_info->csf_if->unlock(csf_info->csf_if->ctx, flags);
1636 return;
1637 }
1638
1639 kbasep_hwcnt_backend_csf_handle_unrecoverable_error(csf_info->backend);
1640
1641 csf_info->csf_if->unlock(csf_info->csf_if->ctx, flags);
1642 }
1643
kbase_hwcnt_backend_csf_on_before_reset(struct kbase_hwcnt_backend_interface * iface)1644 void kbase_hwcnt_backend_csf_on_before_reset(struct kbase_hwcnt_backend_interface *iface)
1645 {
1646 unsigned long flags = 0UL;
1647 struct kbase_hwcnt_backend_csf_info *csf_info;
1648 struct kbase_hwcnt_backend_csf *backend_csf;
1649
1650 csf_info = (struct kbase_hwcnt_backend_csf_info *)iface->info;
1651
1652 csf_info->csf_if->lock(csf_info->csf_if->ctx, &flags);
1653 csf_info->unrecoverable_error_happened = false;
1654 /* Early out if the backend does not exist. */
1655 if (!kbasep_hwcnt_backend_csf_backend_exists(csf_info)) {
1656 csf_info->csf_if->unlock(csf_info->csf_if->ctx, flags);
1657 return;
1658 }
1659 backend_csf = csf_info->backend;
1660
1661 if ((backend_csf->enable_state != KBASE_HWCNT_BACKEND_CSF_DISABLED) &&
1662 (backend_csf->enable_state != KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR)) {
1663 /* Before a reset occurs, we must either have been disabled
1664 * (else we lose data) or we should have encountered an
1665 * unrecoverable error. Either way, we will have disabled the
1666 * interface and waited for any workers that might have still
1667 * been in flight.
1668 * If not in these states, fire off one more disable to make
1669 * sure everything is turned off before the power is pulled.
1670 * We can't wait for this disable to complete, but it doesn't
1671 * really matter, the power is being pulled.
1672 */
1673 kbasep_hwcnt_backend_csf_handle_unrecoverable_error(csf_info->backend);
1674 }
1675
1676 /* A reset is the only way to exit the unrecoverable error state */
1677 if (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_UNRECOVERABLE_ERROR) {
1678 kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(
1679 backend_csf, KBASE_HWCNT_BACKEND_CSF_DISABLED);
1680 }
1681
1682 csf_info->csf_if->unlock(csf_info->csf_if->ctx, flags);
1683 }
1684
kbase_hwcnt_backend_csf_on_prfcnt_sample(struct kbase_hwcnt_backend_interface * iface)1685 void kbase_hwcnt_backend_csf_on_prfcnt_sample(struct kbase_hwcnt_backend_interface *iface)
1686 {
1687 struct kbase_hwcnt_backend_csf_info *csf_info;
1688 struct kbase_hwcnt_backend_csf *backend_csf;
1689
1690 csf_info = (struct kbase_hwcnt_backend_csf_info *)iface->info;
1691 csf_info->csf_if->assert_lock_held(csf_info->csf_if->ctx);
1692
1693 /* Early out if the backend does not exist. */
1694 if (!kbasep_hwcnt_backend_csf_backend_exists(csf_info))
1695 return;
1696 backend_csf = csf_info->backend;
1697
1698 /* Skip the dump_work if it's a watchdog request. */
1699 if (backend_csf->dump_state == KBASE_HWCNT_BACKEND_CSF_DUMP_WATCHDOG_REQUESTED) {
1700 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_COMPLETED;
1701 return;
1702 }
1703
1704 /* If the current state is not REQUESTED, this HWC sample will be
1705 * skipped and processed in next dump_request.
1706 */
1707 if (backend_csf->dump_state != KBASE_HWCNT_BACKEND_CSF_DUMP_REQUESTED)
1708 return;
1709 backend_csf->dump_state = KBASE_HWCNT_BACKEND_CSF_DUMP_QUERYING_INSERT;
1710
1711 kbase_hwcnt_backend_csf_submit_dump_worker(csf_info);
1712 }
1713
kbase_hwcnt_backend_csf_on_prfcnt_threshold(struct kbase_hwcnt_backend_interface * iface)1714 void kbase_hwcnt_backend_csf_on_prfcnt_threshold(struct kbase_hwcnt_backend_interface *iface)
1715 {
1716 struct kbase_hwcnt_backend_csf_info *csf_info;
1717 struct kbase_hwcnt_backend_csf *backend_csf;
1718
1719 csf_info = (struct kbase_hwcnt_backend_csf_info *)iface->info;
1720 csf_info->csf_if->assert_lock_held(csf_info->csf_if->ctx);
1721
1722 /* Early out if the backend does not exist. */
1723 if (!kbasep_hwcnt_backend_csf_backend_exists(csf_info))
1724 return;
1725 backend_csf = csf_info->backend;
1726
1727 if (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_ENABLED)
1728 /* Submit the threshold work into the work queue to consume the
1729 * available samples.
1730 */
1731 queue_work(backend_csf->hwc_dump_workq, &backend_csf->hwc_threshold_work);
1732 }
1733
kbase_hwcnt_backend_csf_on_prfcnt_overflow(struct kbase_hwcnt_backend_interface * iface)1734 void kbase_hwcnt_backend_csf_on_prfcnt_overflow(struct kbase_hwcnt_backend_interface *iface)
1735 {
1736 struct kbase_hwcnt_backend_csf_info *csf_info;
1737
1738 csf_info = (struct kbase_hwcnt_backend_csf_info *)iface->info;
1739 csf_info->csf_if->assert_lock_held(csf_info->csf_if->ctx);
1740
1741 /* Early out if the backend does not exist. */
1742 if (!kbasep_hwcnt_backend_csf_backend_exists(csf_info))
1743 return;
1744
1745 /* Called when an overflow occurs. We treat this as a recoverable error,
1746 * so we start transitioning to the disabled state.
1747 * We could try and handle it while enabled, but in a real system we
1748 * never expect an overflow to occur so there is no point implementing
1749 * complex recovery code when we can just turn ourselves off instead for
1750 * a while.
1751 */
1752 kbasep_hwcnt_backend_csf_handle_recoverable_error(csf_info->backend);
1753 }
1754
kbase_hwcnt_backend_csf_on_prfcnt_enable(struct kbase_hwcnt_backend_interface * iface)1755 void kbase_hwcnt_backend_csf_on_prfcnt_enable(struct kbase_hwcnt_backend_interface *iface)
1756 {
1757 struct kbase_hwcnt_backend_csf_info *csf_info;
1758 struct kbase_hwcnt_backend_csf *backend_csf;
1759
1760 csf_info = (struct kbase_hwcnt_backend_csf_info *)iface->info;
1761 csf_info->csf_if->assert_lock_held(csf_info->csf_if->ctx);
1762
1763 /* Early out if the backend does not exist. */
1764 if (!kbasep_hwcnt_backend_csf_backend_exists(csf_info))
1765 return;
1766 backend_csf = csf_info->backend;
1767
1768 if (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_ENABLED) {
1769 kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(
1770 backend_csf, KBASE_HWCNT_BACKEND_CSF_ENABLED);
1771 } else if (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_ENABLED) {
1772 /* Unexpected, but we are already in the right state so just
1773 * ignore it.
1774 */
1775 } else {
1776 /* Unexpected state change, assume everything is broken until
1777 * we reset.
1778 */
1779 kbasep_hwcnt_backend_csf_handle_unrecoverable_error(csf_info->backend);
1780 }
1781 }
1782
kbase_hwcnt_backend_csf_on_prfcnt_disable(struct kbase_hwcnt_backend_interface * iface)1783 void kbase_hwcnt_backend_csf_on_prfcnt_disable(struct kbase_hwcnt_backend_interface *iface)
1784 {
1785 struct kbase_hwcnt_backend_csf_info *csf_info;
1786 struct kbase_hwcnt_backend_csf *backend_csf;
1787
1788 csf_info = (struct kbase_hwcnt_backend_csf_info *)iface->info;
1789 csf_info->csf_if->assert_lock_held(csf_info->csf_if->ctx);
1790
1791 /* Early out if the backend does not exist. */
1792 if (!kbasep_hwcnt_backend_csf_backend_exists(csf_info))
1793 return;
1794 backend_csf = csf_info->backend;
1795
1796 if (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_TRANSITIONING_TO_DISABLED) {
1797 kbasep_hwcnt_backend_csf_change_es_and_wake_waiters(
1798 backend_csf, KBASE_HWCNT_BACKEND_CSF_DISABLED_WAIT_FOR_WORKER);
1799 } else if (backend_csf->enable_state == KBASE_HWCNT_BACKEND_CSF_DISABLED) {
1800 /* Unexpected, but we are already in the right state so just
1801 * ignore it.
1802 */
1803 } else {
1804 /* Unexpected state change, assume everything is broken until
1805 * we reset.
1806 */
1807 kbasep_hwcnt_backend_csf_handle_unrecoverable_error(csf_info->backend);
1808 }
1809 }
1810
kbase_hwcnt_backend_csf_metadata_init(struct kbase_hwcnt_backend_interface * iface)1811 int kbase_hwcnt_backend_csf_metadata_init(struct kbase_hwcnt_backend_interface *iface)
1812 {
1813 struct kbase_hwcnt_backend_csf_info *csf_info;
1814 struct kbase_hwcnt_gpu_info gpu_info;
1815
1816 if (!iface)
1817 return -EINVAL;
1818
1819 csf_info = (struct kbase_hwcnt_backend_csf_info *)iface->info;
1820
1821 WARN_ON(!csf_info->csf_if->get_prfcnt_info);
1822
1823 csf_info->csf_if->get_prfcnt_info(csf_info->csf_if->ctx, &csf_info->prfcnt_info);
1824
1825 /* The clock domain counts should not exceed the number of maximum
1826 * number of clock regulators.
1827 */
1828 if (csf_info->prfcnt_info.clk_cnt > BASE_MAX_NR_CLOCKS_REGULATORS)
1829 return -EIO;
1830
1831 gpu_info.l2_count = csf_info->prfcnt_info.l2_count;
1832 gpu_info.core_mask = csf_info->prfcnt_info.core_mask;
1833 gpu_info.clk_cnt = csf_info->prfcnt_info.clk_cnt;
1834 gpu_info.prfcnt_values_per_block =
1835 csf_info->prfcnt_info.prfcnt_block_size / KBASE_HWCNT_VALUE_HW_BYTES;
1836 return kbase_hwcnt_csf_metadata_create(&gpu_info, csf_info->counter_set,
1837 &csf_info->metadata);
1838 }
1839
kbase_hwcnt_backend_csf_metadata_term(struct kbase_hwcnt_backend_interface * iface)1840 void kbase_hwcnt_backend_csf_metadata_term(struct kbase_hwcnt_backend_interface *iface)
1841 {
1842 struct kbase_hwcnt_backend_csf_info *csf_info;
1843
1844 if (!iface)
1845 return;
1846
1847 csf_info = (struct kbase_hwcnt_backend_csf_info *)iface->info;
1848 if (csf_info->metadata) {
1849 kbase_hwcnt_csf_metadata_destroy(csf_info->metadata);
1850 csf_info->metadata = NULL;
1851 }
1852 }
1853
kbase_hwcnt_backend_csf_create(struct kbase_hwcnt_backend_csf_if * csf_if,u32 ring_buf_cnt,struct kbase_hwcnt_watchdog_interface * watchdog_if,struct kbase_hwcnt_backend_interface * iface)1854 int kbase_hwcnt_backend_csf_create(struct kbase_hwcnt_backend_csf_if *csf_if, u32 ring_buf_cnt,
1855 struct kbase_hwcnt_watchdog_interface *watchdog_if,
1856 struct kbase_hwcnt_backend_interface *iface)
1857 {
1858 int errcode;
1859 const struct kbase_hwcnt_backend_csf_info *info = NULL;
1860
1861 if (!iface || !csf_if || !watchdog_if)
1862 return -EINVAL;
1863
1864 /* The buffer count must be power of 2 */
1865 if (!is_power_of_2(ring_buf_cnt))
1866 return -EINVAL;
1867
1868 errcode = kbasep_hwcnt_backend_csf_info_create(csf_if, ring_buf_cnt, watchdog_if, &info);
1869 if (errcode)
1870 return errcode;
1871
1872 iface->info = (struct kbase_hwcnt_backend_info *)info;
1873 iface->metadata = kbasep_hwcnt_backend_csf_metadata;
1874 iface->init = kbasep_hwcnt_backend_csf_init;
1875 iface->term = kbasep_hwcnt_backend_csf_term;
1876 iface->timestamp_ns = kbasep_hwcnt_backend_csf_timestamp_ns;
1877 iface->dump_enable = kbasep_hwcnt_backend_csf_dump_enable;
1878 iface->dump_enable_nolock = kbasep_hwcnt_backend_csf_dump_enable_nolock;
1879 iface->dump_disable = kbasep_hwcnt_backend_csf_dump_disable;
1880 iface->dump_clear = kbasep_hwcnt_backend_csf_dump_clear;
1881 iface->dump_request = kbasep_hwcnt_backend_csf_dump_request;
1882 iface->dump_wait = kbasep_hwcnt_backend_csf_dump_wait;
1883 iface->dump_get = kbasep_hwcnt_backend_csf_dump_get;
1884
1885 return 0;
1886 }
1887
kbase_hwcnt_backend_csf_destroy(struct kbase_hwcnt_backend_interface * iface)1888 void kbase_hwcnt_backend_csf_destroy(struct kbase_hwcnt_backend_interface *iface)
1889 {
1890 if (!iface)
1891 return;
1892
1893 kbasep_hwcnt_backend_csf_info_destroy(
1894 (const struct kbase_hwcnt_backend_csf_info *)iface->info);
1895 memset(iface, 0, sizeof(*iface));
1896 }
1897