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