• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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