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