1 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
2 /*
3 *
4 * (C) COPYRIGHT 2014-2022 ARM Limited. All rights reserved.
5 *
6 * This program is free software and is provided to you under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation, and any use by you of this program is subject to the terms
9 * of such GNU license.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you can access it online at
18 * http://www.gnu.org/licenses/gpl-2.0.html.
19 *
20 */
21
22 /* NOTES:
23 * - A default GPU can be compiled in during the build, by defining
24 * CONFIG_MALI_NO_MALI_DEFAULT_GPU. SCons sets this, which means that
25 * insmod'ing mali_kbase.ko with no arguments after a build with "scons
26 * gpu=tXYZ" will yield the expected GPU ID for tXYZ. This can always be
27 * overridden by passing the 'no_mali_gpu' argument to insmod.
28 *
29 * - if CONFIG_MALI_BIFROST_ERROR_INJECT is defined the error injection system is
30 * activated.
31 */
32
33 /* Implementation of failure injection system:
34 *
35 * Error conditions are generated by gpu_generate_error().
36 * According to CONFIG_MALI_BIFROST_ERROR_INJECT definition gpu_generate_error() either
37 * generates an error HW condition randomly (CONFIG_MALI_ERROR_INJECT_RANDOM) or
38 * checks if there is (in error_track_list) an error configuration to be set for
39 * the current job chain (CONFIG_MALI_ERROR_INJECT_RANDOM not defined).
40 * Each error condition will trigger a specific "state" for a certain set of
41 * registers as per Midgard Architecture Specifications doc.
42 *
43 * According to Midgard Architecture Specifications doc the following registers
44 * are always affected by error conditions:
45 *
46 * JOB Exception:
47 * JOB_IRQ_RAWSTAT
48 * JOB<n> STATUS AREA
49 *
50 * MMU Exception:
51 * MMU_IRQ_RAWSTAT
52 * AS<n>_FAULTSTATUS
53 * AS<n>_FAULTADDRESS
54 *
55 * GPU Exception:
56 * GPU_IRQ_RAWSTAT
57 * GPU_FAULTSTATUS
58 * GPU_FAULTADDRESS
59 *
60 * For further clarification on the model behaviour upon specific error
61 * conditions the user may refer to the Midgard Architecture Specification
62 * document
63 */
64 #include <mali_kbase.h>
65 #include <device/mali_kbase_device.h>
66 #include <gpu/mali_kbase_gpu_regmap.h>
67 #include <backend/gpu/mali_kbase_model_linux.h>
68 #include <mali_kbase_mem_linux.h>
69
70 #if MALI_USE_CSF
71 #include <csf/mali_kbase_csf_firmware.h>
72
73 /* Index of the last value register for each type of core, with the 1st value
74 * register being at index 0.
75 */
76 #define IPA_CTL_MAX_VAL_CNT_IDX (KBASE_IPA_CONTROL_NUM_BLOCK_COUNTERS - 1)
77
78 /* Array for storing the value of SELECT register for each type of core */
79 static u64 ipa_ctl_select_config[KBASE_IPA_CORE_TYPE_NUM];
80 static bool ipa_control_timer_enabled;
81 #endif
82
83 #define LO_MASK(M) ((M) & 0xFFFFFFFF)
84 #if !MALI_USE_CSF
85 #define HI_MASK(M) ((M) & 0xFFFFFFFF00000000)
86 #endif
87
88 /* Construct a value for the THREAD_FEATURES register, *except* the two most
89 * significant bits, which are set to IMPLEMENTATION_MODEL in
90 * midgard_model_read_reg().
91 */
92 #if MALI_USE_CSF
93 #define THREAD_FEATURES_PARTIAL(MAX_REGISTERS, MAX_TASK_QUEUE, MAX_TG_SPLIT) \
94 ((MAX_REGISTERS) | ((MAX_TASK_QUEUE) << 24))
95 #else
96 #define THREAD_FEATURES_PARTIAL(MAX_REGISTERS, MAX_TASK_QUEUE, MAX_TG_SPLIT) \
97 ((MAX_REGISTERS) | ((MAX_TASK_QUEUE) << 16) | ((MAX_TG_SPLIT) << 24))
98 #endif
99
100 struct error_status_t hw_error_status;
101
102 /**
103 * struct control_reg_values_t - control register values specific to the GPU being 'emulated'
104 * @name: GPU name
105 * @gpu_id: GPU ID to report
106 * @as_present: Bitmap of address spaces present
107 * @thread_max_threads: Maximum number of threads per core
108 * @thread_max_workgroup_size: Maximum number of threads per workgroup
109 * @thread_max_barrier_size: Maximum number of threads per barrier
110 * @thread_features: Thread features, NOT INCLUDING the 2
111 * most-significant bits, which are always set to
112 * IMPLEMENTATION_MODEL.
113 * @core_features: Core features
114 * @tiler_features: Tiler features
115 * @mmu_features: MMU features
116 * @gpu_features_lo: GPU features (low)
117 * @gpu_features_hi: GPU features (high)
118 * @shader_present: Available shader bitmap
119 * @stack_present: Core stack present bitmap
120 *
121 */
122 struct control_reg_values_t {
123 const char *name;
124 u32 gpu_id;
125 u32 as_present;
126 u32 thread_max_threads;
127 u32 thread_max_workgroup_size;
128 u32 thread_max_barrier_size;
129 u32 thread_features;
130 u32 core_features;
131 u32 tiler_features;
132 u32 mmu_features;
133 u32 gpu_features_lo;
134 u32 gpu_features_hi;
135 u32 shader_present;
136 u32 stack_present;
137 };
138
139 struct job_slot {
140 int job_active;
141 int job_queued;
142 int job_complete_irq_asserted;
143 int job_irq_mask;
144 int job_disabled;
145 };
146
147 struct dummy_model_t {
148 int reset_completed;
149 int reset_completed_mask;
150 #if !MALI_USE_CSF
151 int prfcnt_sample_completed;
152 #endif /* !MALI_USE_CSF */
153 int power_changed_mask; /* 2bits: _ALL,_SINGLE */
154 int power_changed; /* 1bit */
155 bool clean_caches_completed;
156 bool clean_caches_completed_irq_enabled;
157 #if MALI_USE_CSF
158 bool flush_pa_range_completed;
159 bool flush_pa_range_completed_irq_enabled;
160 #endif
161 int power_on; /* 6bits: SHADER[4],TILER,L2 */
162 u32 stack_power_on_lo;
163 u32 coherency_enable;
164 unsigned int job_irq_js_state;
165 struct job_slot slots[NUM_SLOTS];
166 const struct control_reg_values_t *control_reg_values;
167 u32 l2_config;
168 void *data;
169 };
170
171 /* Array associating GPU names with control register values. The first
172 * one is used in the case of no match.
173 */
174 static const struct control_reg_values_t all_control_reg_values[] = {
175 {
176 .name = "tMIx",
177 .gpu_id = GPU_ID2_MAKE(6, 0, 10, 0, 0, 1, 0),
178 .as_present = 0xFF,
179 .thread_max_threads = 0x180,
180 .thread_max_workgroup_size = 0x180,
181 .thread_max_barrier_size = 0x180,
182 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 10),
183 .tiler_features = 0x809,
184 .mmu_features = 0x2830,
185 .gpu_features_lo = 0,
186 .gpu_features_hi = 0,
187 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
188 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
189 },
190 {
191 .name = "tHEx",
192 .gpu_id = GPU_ID2_MAKE(6, 2, 0, 1, 0, 3, 0),
193 .as_present = 0xFF,
194 .thread_max_threads = 0x180,
195 .thread_max_workgroup_size = 0x180,
196 .thread_max_barrier_size = 0x180,
197 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 10),
198 .tiler_features = 0x809,
199 .mmu_features = 0x2830,
200 .gpu_features_lo = 0,
201 .gpu_features_hi = 0,
202 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
203 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
204 },
205 {
206 .name = "tSIx",
207 .gpu_id = GPU_ID2_MAKE(7, 0, 0, 0, 1, 1, 0),
208 .as_present = 0xFF,
209 .thread_max_threads = 0x300,
210 .thread_max_workgroup_size = 0x180,
211 .thread_max_barrier_size = 0x180,
212 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 10),
213 .tiler_features = 0x209,
214 .mmu_features = 0x2821,
215 .gpu_features_lo = 0,
216 .gpu_features_hi = 0,
217 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
218 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
219 },
220 {
221 .name = "tDVx",
222 .gpu_id = GPU_ID2_MAKE(7, 0, 0, 3, 0, 0, 0),
223 .as_present = 0xFF,
224 .thread_max_threads = 0x300,
225 .thread_max_workgroup_size = 0x180,
226 .thread_max_barrier_size = 0x180,
227 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 10),
228 .tiler_features = 0x209,
229 .mmu_features = 0x2821,
230 .gpu_features_lo = 0,
231 .gpu_features_hi = 0,
232 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
233 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
234 },
235 {
236 .name = "tNOx",
237 .gpu_id = GPU_ID2_MAKE(7, 2, 1, 1, 0, 0, 0),
238 .as_present = 0xFF,
239 .thread_max_threads = 0x180,
240 .thread_max_workgroup_size = 0x180,
241 .thread_max_barrier_size = 0x180,
242 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 10),
243 .tiler_features = 0x809,
244 .mmu_features = 0x2830,
245 .gpu_features_lo = 0,
246 .gpu_features_hi = 0,
247 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
248 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
249 },
250 {
251 .name = "tGOx_r0p0",
252 .gpu_id = GPU_ID2_MAKE(7, 2, 2, 2, 0, 0, 0),
253 .as_present = 0xFF,
254 .thread_max_threads = 0x180,
255 .thread_max_workgroup_size = 0x180,
256 .thread_max_barrier_size = 0x180,
257 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 10),
258 .tiler_features = 0x809,
259 .mmu_features = 0x2830,
260 .gpu_features_lo = 0,
261 .gpu_features_hi = 0,
262 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
263 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
264 },
265 {
266 .name = "tGOx_r1p0",
267 .gpu_id = GPU_ID2_MAKE(7, 4, 0, 2, 1, 0, 0),
268 .as_present = 0xFF,
269 .thread_max_threads = 0x180,
270 .thread_max_workgroup_size = 0x180,
271 .thread_max_barrier_size = 0x180,
272 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 10),
273 .core_features = 0x2,
274 .tiler_features = 0x209,
275 .mmu_features = 0x2823,
276 .gpu_features_lo = 0,
277 .gpu_features_hi = 0,
278 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
279 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
280 },
281 {
282 .name = "tTRx",
283 .gpu_id = GPU_ID2_MAKE(9, 0, 8, 0, 0, 0, 0),
284 .as_present = 0xFF,
285 .thread_max_threads = 0x180,
286 .thread_max_workgroup_size = 0x180,
287 .thread_max_barrier_size = 0x180,
288 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 0),
289 .tiler_features = 0x809,
290 .mmu_features = 0x2830,
291 .gpu_features_lo = 0,
292 .gpu_features_hi = 0,
293 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
294 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
295 },
296 {
297 .name = "tNAx",
298 .gpu_id = GPU_ID2_MAKE(9, 0, 8, 1, 0, 0, 0),
299 .as_present = 0xFF,
300 .thread_max_threads = 0x180,
301 .thread_max_workgroup_size = 0x180,
302 .thread_max_barrier_size = 0x180,
303 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 0),
304 .tiler_features = 0x809,
305 .mmu_features = 0x2830,
306 .gpu_features_lo = 0,
307 .gpu_features_hi = 0,
308 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
309 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
310 },
311 {
312 .name = "tBEx",
313 .gpu_id = GPU_ID2_MAKE(9, 2, 0, 2, 0, 0, 0),
314 .as_present = 0xFF,
315 .thread_max_threads = 0x180,
316 .thread_max_workgroup_size = 0x180,
317 .thread_max_barrier_size = 0x180,
318 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 0),
319 .tiler_features = 0x809,
320 .mmu_features = 0x2830,
321 .gpu_features_lo = 0,
322 .gpu_features_hi = 0,
323 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT_TBEX,
324 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
325 },
326 {
327 .name = "tBAx",
328 .gpu_id = GPU_ID2_MAKE(9, 14, 4, 5, 0, 0, 0),
329 .as_present = 0xFF,
330 .thread_max_threads = 0x180,
331 .thread_max_workgroup_size = 0x180,
332 .thread_max_barrier_size = 0x180,
333 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 0),
334 .tiler_features = 0x809,
335 .mmu_features = 0x2830,
336 .gpu_features_lo = 0,
337 .gpu_features_hi = 0,
338 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
339 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
340 },
341 {
342 .name = "tODx",
343 .gpu_id = GPU_ID2_MAKE(10, 8, 0, 2, 0, 0, 0),
344 .as_present = 0xFF,
345 .thread_max_threads = 0x180,
346 .thread_max_workgroup_size = 0x180,
347 .thread_max_barrier_size = 0x180,
348 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 0),
349 .tiler_features = 0x809,
350 .mmu_features = 0x2830,
351 .gpu_features_lo = 0,
352 .gpu_features_hi = 0,
353 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT_TODX,
354 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
355 },
356 {
357 .name = "tGRx",
358 .gpu_id = GPU_ID2_MAKE(10, 10, 0, 3, 0, 0, 0),
359 .as_present = 0xFF,
360 .thread_max_threads = 0x180,
361 .thread_max_workgroup_size = 0x180,
362 .thread_max_barrier_size = 0x180,
363 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 0),
364 .core_features = 0x0, /* core_1e16fma2tex */
365 .tiler_features = 0x809,
366 .mmu_features = 0x2830,
367 .gpu_features_lo = 0,
368 .gpu_features_hi = 0,
369 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
370 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
371 },
372 {
373 .name = "tVAx",
374 .gpu_id = GPU_ID2_MAKE(10, 12, 0, 4, 0, 0, 0),
375 .as_present = 0xFF,
376 .thread_max_threads = 0x180,
377 .thread_max_workgroup_size = 0x180,
378 .thread_max_barrier_size = 0x180,
379 .thread_features = THREAD_FEATURES_PARTIAL(0x6000, 4, 0),
380 .core_features = 0x0, /* core_1e16fma2tex */
381 .tiler_features = 0x809,
382 .mmu_features = 0x2830,
383 .gpu_features_lo = 0,
384 .gpu_features_hi = 0,
385 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT,
386 .stack_present = DUMMY_IMPLEMENTATION_STACK_PRESENT,
387 },
388 {
389 .name = "tTUx",
390 .gpu_id = GPU_ID2_MAKE(11, 8, 5, 2, 0, 0, 0),
391 .as_present = 0xFF,
392 .thread_max_threads = 0x800,
393 .thread_max_workgroup_size = 0x400,
394 .thread_max_barrier_size = 0x400,
395 .thread_features = THREAD_FEATURES_PARTIAL(0x10000, 4, 0),
396 .core_features = 0x0, /* core_1e32fma2tex */
397 .tiler_features = 0x809,
398 .mmu_features = 0x2830,
399 .gpu_features_lo = 0xf,
400 .gpu_features_hi = 0,
401 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT_TTUX,
402 .stack_present = 0xF,
403 },
404 {
405 .name = "tTIx",
406 .gpu_id = GPU_ID2_MAKE(12, 8, 1, 0, 0, 0, 0),
407 .as_present = 0xFF,
408 .thread_max_threads = 0x800,
409 .thread_max_workgroup_size = 0x400,
410 .thread_max_barrier_size = 0x400,
411 .thread_features = THREAD_FEATURES_PARTIAL(0x10000, 16, 0),
412 .core_features = 0x1, /* core_1e64fma4tex */
413 .tiler_features = 0x809,
414 .mmu_features = 0x2830,
415 .gpu_features_lo = 0xf,
416 .gpu_features_hi = 0,
417 .shader_present = DUMMY_IMPLEMENTATION_SHADER_PRESENT_TTIX,
418 .stack_present = 0xF,
419 },
420 };
421
422 static struct {
423 spinlock_t access_lock;
424 #if !MALI_USE_CSF
425 unsigned long prfcnt_base;
426 #endif /* !MALI_USE_CSF */
427 u32 *prfcnt_base_cpu;
428
429 u32 time;
430
431 struct gpu_model_prfcnt_en prfcnt_en;
432
433 u64 l2_present;
434 u64 shader_present;
435
436 #if !MALI_USE_CSF
437 u64 jm_counters[KBASE_DUMMY_MODEL_COUNTER_PER_CORE];
438 #else
439 u64 cshw_counters[KBASE_DUMMY_MODEL_COUNTER_PER_CORE];
440 #endif /* !MALI_USE_CSF */
441 u64 tiler_counters[KBASE_DUMMY_MODEL_COUNTER_PER_CORE];
442 u64 l2_counters[KBASE_DUMMY_MODEL_MAX_MEMSYS_BLOCKS *
443 KBASE_DUMMY_MODEL_COUNTER_PER_CORE];
444 u64 shader_counters[KBASE_DUMMY_MODEL_MAX_SHADER_CORES *
445 KBASE_DUMMY_MODEL_COUNTER_PER_CORE];
446 } performance_counters;
447
get_implementation_register(u32 reg,const struct control_reg_values_t * const control_reg_values)448 static u32 get_implementation_register(u32 reg,
449 const struct control_reg_values_t *const control_reg_values)
450 {
451 switch (reg) {
452 case GPU_CONTROL_REG(SHADER_PRESENT_LO):
453 return LO_MASK(control_reg_values->shader_present);
454 case GPU_CONTROL_REG(TILER_PRESENT_LO):
455 return LO_MASK(DUMMY_IMPLEMENTATION_TILER_PRESENT);
456 case GPU_CONTROL_REG(L2_PRESENT_LO):
457 return LO_MASK(DUMMY_IMPLEMENTATION_L2_PRESENT);
458 case GPU_CONTROL_REG(STACK_PRESENT_LO):
459 return LO_MASK(control_reg_values->stack_present);
460
461 case GPU_CONTROL_REG(SHADER_PRESENT_HI):
462 case GPU_CONTROL_REG(TILER_PRESENT_HI):
463 case GPU_CONTROL_REG(L2_PRESENT_HI):
464 case GPU_CONTROL_REG(STACK_PRESENT_HI):
465 /* *** FALLTHROUGH *** */
466 default:
467 return 0;
468 }
469 }
470
gpu_device_set_data(void * model,void * data)471 void gpu_device_set_data(void *model, void *data)
472 {
473 struct dummy_model_t *dummy = (struct dummy_model_t *)model;
474
475 dummy->data = data;
476 }
477
gpu_device_get_data(void * model)478 void *gpu_device_get_data(void *model)
479 {
480 struct dummy_model_t *dummy = (struct dummy_model_t *)model;
481
482 return dummy->data;
483 }
484
485 #define signal_int(m, s) m->slots[(s)].job_complete_irq_asserted = 1
486
487 /* SCons should pass in a default GPU, but other ways of building (e.g.
488 * in-tree) won't, so define one here in case.
489 */
490 #ifndef CONFIG_MALI_NO_MALI_DEFAULT_GPU
491 #define CONFIG_MALI_NO_MALI_DEFAULT_GPU "tMIx"
492 #endif
493
494 static char *no_mali_gpu = CONFIG_MALI_NO_MALI_DEFAULT_GPU;
495 module_param(no_mali_gpu, charp, 0000);
496 MODULE_PARM_DESC(no_mali_gpu, "GPU to identify as");
497
498 #if MALI_USE_CSF
gpu_model_get_prfcnt_value(enum kbase_ipa_core_type core_type,u32 cnt_idx,bool is_low_word)499 static u32 gpu_model_get_prfcnt_value(enum kbase_ipa_core_type core_type,
500 u32 cnt_idx, bool is_low_word)
501 {
502 u64 *counters_data;
503 u32 core_count = 0;
504 u32 event_index;
505 u64 value = 0;
506 u32 core;
507 unsigned long flags;
508
509 if (WARN_ON(core_type >= KBASE_IPA_CORE_TYPE_NUM))
510 return 0;
511
512 if (WARN_ON(cnt_idx >= KBASE_IPA_CONTROL_NUM_BLOCK_COUNTERS))
513 return 0;
514
515 event_index =
516 (ipa_ctl_select_config[core_type] >> (cnt_idx * 8)) & 0xFF;
517
518 /* Currently only primary counter blocks are supported */
519 if (WARN_ON(event_index >=
520 (KBASE_DUMMY_MODEL_COUNTER_HEADER_DWORDS + KBASE_DUMMY_MODEL_COUNTER_PER_CORE)))
521 return 0;
522
523 /* The actual events start index 4 onwards. Spec also says PRFCNT_EN,
524 * TIMESTAMP_LO or TIMESTAMP_HI pseudo-counters do not make sense for
525 * IPA counters. If selected, the value returned for them will be zero.
526 */
527 if (WARN_ON(event_index < KBASE_DUMMY_MODEL_COUNTER_HEADER_DWORDS))
528 return 0;
529
530 event_index -= KBASE_DUMMY_MODEL_COUNTER_HEADER_DWORDS;
531
532 spin_lock_irqsave(&performance_counters.access_lock, flags);
533
534 switch (core_type) {
535 case KBASE_IPA_CORE_TYPE_CSHW:
536 core_count = 1;
537 counters_data = performance_counters.cshw_counters;
538 break;
539 case KBASE_IPA_CORE_TYPE_MEMSYS:
540 core_count = hweight64(performance_counters.l2_present);
541 counters_data = performance_counters.l2_counters;
542 break;
543 case KBASE_IPA_CORE_TYPE_TILER:
544 core_count = 1;
545 counters_data = performance_counters.tiler_counters;
546 break;
547 case KBASE_IPA_CORE_TYPE_SHADER:
548 core_count = hweight64(performance_counters.shader_present);
549 counters_data = performance_counters.shader_counters;
550 break;
551 default:
552 WARN(1, "Invalid core_type %d\n", core_type);
553 break;
554 }
555
556 for (core = 0; core < core_count; core++) {
557 value += counters_data[event_index];
558 event_index += KBASE_DUMMY_MODEL_COUNTER_PER_CORE;
559 }
560
561 spin_unlock_irqrestore(&performance_counters.access_lock, flags);
562
563 if (is_low_word)
564 return (value & U32_MAX);
565 else
566 return (value >> 32);
567 }
568 #endif /* MALI_USE_CSF */
569
570 /**
571 * gpu_model_clear_prfcnt_values_nolock - Clear performance counter values
572 *
573 * Sets all performance counter values to zero. The performance counter access
574 * lock must be held when calling this function.
575 */
gpu_model_clear_prfcnt_values_nolock(void)576 static void gpu_model_clear_prfcnt_values_nolock(void)
577 {
578 lockdep_assert_held(&performance_counters.access_lock);
579 #if !MALI_USE_CSF
580 memset(performance_counters.jm_counters, 0, sizeof(performance_counters.jm_counters));
581 #else
582 memset(performance_counters.cshw_counters, 0, sizeof(performance_counters.cshw_counters));
583 #endif /* !MALI_USE_CSF */
584 memset(performance_counters.tiler_counters, 0, sizeof(performance_counters.tiler_counters));
585 memset(performance_counters.l2_counters, 0, sizeof(performance_counters.l2_counters));
586 memset(performance_counters.shader_counters, 0,
587 sizeof(performance_counters.shader_counters));
588 }
589
590 #if MALI_USE_CSF
gpu_model_clear_prfcnt_values(void)591 void gpu_model_clear_prfcnt_values(void)
592 {
593 unsigned long flags;
594
595 spin_lock_irqsave(&performance_counters.access_lock, flags);
596 gpu_model_clear_prfcnt_values_nolock();
597 spin_unlock_irqrestore(&performance_counters.access_lock, flags);
598 }
599 KBASE_EXPORT_TEST_API(gpu_model_clear_prfcnt_values);
600 #endif /* MALI_USE_CSF */
601
602 /**
603 * gpu_model_dump_prfcnt_blocks() - Dump performance counter values to buffer
604 *
605 * @values: Array of values to be written out
606 * @out_index: Index into performance counter buffer
607 * @block_count: Number of blocks to dump
608 * @prfcnt_enable_mask: Counter enable mask
609 * @blocks_present: Available blocks bit mask
610 *
611 * The performance counter access lock must be held before calling this
612 * function.
613 */
gpu_model_dump_prfcnt_blocks(u64 * values,u32 * out_index,u32 block_count,u32 prfcnt_enable_mask,u64 blocks_present)614 static void gpu_model_dump_prfcnt_blocks(u64 *values, u32 *out_index, u32 block_count,
615 u32 prfcnt_enable_mask, u64 blocks_present)
616 {
617 u32 block_idx, counter;
618 u32 counter_value = 0;
619 u32 *prfcnt_base;
620 u32 index = 0;
621
622 lockdep_assert_held(&performance_counters.access_lock);
623
624 prfcnt_base = performance_counters.prfcnt_base_cpu;
625
626 for (block_idx = 0; block_idx < block_count; block_idx++) {
627 /* only dump values if core is present */
628 if (!(blocks_present & (1 << block_idx))) {
629 #if MALI_USE_CSF
630 /* if CSF dump zeroed out block */
631 memset(&prfcnt_base[*out_index], 0,
632 KBASE_DUMMY_MODEL_BLOCK_SIZE);
633 *out_index += KBASE_DUMMY_MODEL_VALUES_PER_BLOCK;
634 #endif /* MALI_USE_CSF */
635 continue;
636 }
637
638 /* write the header */
639 prfcnt_base[*out_index] = performance_counters.time++;
640 prfcnt_base[*out_index+2] = prfcnt_enable_mask;
641 *out_index += KBASE_DUMMY_MODEL_COUNTER_HEADER_DWORDS;
642
643 /* write the counters */
644 for (counter = 0;
645 counter < KBASE_DUMMY_MODEL_COUNTER_PER_CORE;
646 counter++) {
647 /* HW counter values retrieved through
648 * PRFCNT_SAMPLE request are of 32 bits only.
649 */
650 counter_value = (u32)values[index++];
651 if (KBASE_DUMMY_MODEL_COUNTER_ENABLED(
652 prfcnt_enable_mask, (counter +
653 KBASE_DUMMY_MODEL_COUNTER_HEADER_DWORDS))) {
654 prfcnt_base[*out_index + counter] =
655 counter_value;
656 }
657 }
658 *out_index += KBASE_DUMMY_MODEL_COUNTER_PER_CORE;
659 }
660 }
661
gpu_model_dump_nolock(void)662 static void gpu_model_dump_nolock(void)
663 {
664 u32 index = 0;
665
666 lockdep_assert_held(&performance_counters.access_lock);
667
668 #if !MALI_USE_CSF
669 gpu_model_dump_prfcnt_blocks(performance_counters.jm_counters, &index, 1,
670 performance_counters.prfcnt_en.fe, 0x1);
671 #else
672 gpu_model_dump_prfcnt_blocks(performance_counters.cshw_counters, &index, 1,
673 performance_counters.prfcnt_en.fe, 0x1);
674 #endif /* !MALI_USE_CSF */
675 gpu_model_dump_prfcnt_blocks(performance_counters.tiler_counters,
676 &index, 1,
677 performance_counters.prfcnt_en.tiler,
678 DUMMY_IMPLEMENTATION_TILER_PRESENT);
679 gpu_model_dump_prfcnt_blocks(performance_counters.l2_counters, &index,
680 KBASE_DUMMY_MODEL_MAX_MEMSYS_BLOCKS,
681 performance_counters.prfcnt_en.l2,
682 performance_counters.l2_present);
683 gpu_model_dump_prfcnt_blocks(performance_counters.shader_counters,
684 &index, KBASE_DUMMY_MODEL_MAX_SHADER_CORES,
685 performance_counters.prfcnt_en.shader,
686 performance_counters.shader_present);
687
688 /* Counter values are cleared after each dump */
689 gpu_model_clear_prfcnt_values_nolock();
690
691 /* simulate a 'long' time between samples */
692 performance_counters.time += 10;
693 }
694
695 #if !MALI_USE_CSF
midgard_model_dump_prfcnt(void)696 static void midgard_model_dump_prfcnt(void)
697 {
698 unsigned long flags;
699
700 spin_lock_irqsave(&performance_counters.access_lock, flags);
701 gpu_model_dump_nolock();
702 spin_unlock_irqrestore(&performance_counters.access_lock, flags);
703 }
704 #else
gpu_model_prfcnt_dump_request(u32 * sample_buf,struct gpu_model_prfcnt_en enable_maps)705 void gpu_model_prfcnt_dump_request(u32 *sample_buf, struct gpu_model_prfcnt_en enable_maps)
706 {
707 unsigned long flags;
708
709 if (WARN_ON(!sample_buf))
710 return;
711
712 spin_lock_irqsave(&performance_counters.access_lock, flags);
713 performance_counters.prfcnt_base_cpu = sample_buf;
714 performance_counters.prfcnt_en = enable_maps;
715 gpu_model_dump_nolock();
716 spin_unlock_irqrestore(&performance_counters.access_lock, flags);
717 }
718
gpu_model_glb_request_job_irq(void * model)719 void gpu_model_glb_request_job_irq(void *model)
720 {
721 unsigned long flags;
722
723 spin_lock_irqsave(&hw_error_status.access_lock, flags);
724 hw_error_status.job_irq_status |= JOB_IRQ_GLOBAL_IF;
725 spin_unlock_irqrestore(&hw_error_status.access_lock, flags);
726 gpu_device_raise_irq(model, MODEL_LINUX_JOB_IRQ);
727 }
728 #endif /* !MALI_USE_CSF */
729
init_register_statuses(struct dummy_model_t * dummy)730 static void init_register_statuses(struct dummy_model_t *dummy)
731 {
732 int i;
733
734 hw_error_status.errors_mask = 0;
735 hw_error_status.gpu_error_irq = 0;
736 hw_error_status.gpu_fault_status = 0;
737 hw_error_status.job_irq_rawstat = 0;
738 hw_error_status.job_irq_status = 0;
739 hw_error_status.mmu_irq_rawstat = 0;
740 hw_error_status.mmu_irq_mask = 0;
741
742 for (i = 0; i < NUM_SLOTS; i++) {
743 hw_error_status.js_status[i] = 0;
744 hw_error_status.job_irq_rawstat |=
745 (dummy->slots[i].job_complete_irq_asserted) << i;
746 hw_error_status.job_irq_status |=
747 (dummy->slots[i].job_complete_irq_asserted) << i;
748 }
749 for (i = 0; i < NUM_MMU_AS; i++) {
750 hw_error_status.as_command[i] = 0;
751 hw_error_status.as_faultstatus[i] = 0;
752 hw_error_status.mmu_irq_mask |= 1 << i;
753 }
754
755 performance_counters.time = 0;
756 }
757
update_register_statuses(struct dummy_model_t * dummy,unsigned int job_slot)758 static void update_register_statuses(struct dummy_model_t *dummy, unsigned int job_slot)
759 {
760 lockdep_assert_held(&hw_error_status.access_lock);
761
762 if (hw_error_status.errors_mask & IS_A_JOB_ERROR) {
763 if (job_slot == hw_error_status.current_job_slot) {
764 #if !MALI_USE_CSF
765 if (hw_error_status.js_status[job_slot] == 0) {
766 /* status reg is clean; it can be written */
767
768 switch (hw_error_status.errors_mask &
769 IS_A_JOB_ERROR) {
770 case KBASE_JOB_INTERRUPTED:
771 hw_error_status.js_status[job_slot] =
772 JS_STATUS_INTERRUPTED;
773 break;
774
775 case KBASE_JOB_STOPPED:
776 hw_error_status.js_status[job_slot] =
777 JS_STATUS_STOPPED;
778 break;
779
780 case KBASE_JOB_TERMINATED:
781 hw_error_status.js_status[job_slot] =
782 JS_STATUS_TERMINATED;
783 break;
784
785 case KBASE_JOB_CONFIG_FAULT:
786 hw_error_status.js_status[job_slot] =
787 JS_STATUS_CONFIG_FAULT;
788 break;
789
790 case KBASE_JOB_POWER_FAULT:
791 hw_error_status.js_status[job_slot] =
792 JS_STATUS_POWER_FAULT;
793 break;
794
795 case KBASE_JOB_READ_FAULT:
796 hw_error_status.js_status[job_slot] =
797 JS_STATUS_READ_FAULT;
798 break;
799
800 case KBASE_JOB_WRITE_FAULT:
801 hw_error_status.js_status[job_slot] =
802 JS_STATUS_WRITE_FAULT;
803 break;
804
805 case KBASE_JOB_AFFINITY_FAULT:
806 hw_error_status.js_status[job_slot] =
807 JS_STATUS_AFFINITY_FAULT;
808 break;
809
810 case KBASE_JOB_BUS_FAULT:
811 hw_error_status.js_status[job_slot] =
812 JS_STATUS_BUS_FAULT;
813 break;
814
815 case KBASE_INSTR_INVALID_PC:
816 hw_error_status.js_status[job_slot] =
817 JS_STATUS_INSTR_INVALID_PC;
818 break;
819
820 case KBASE_INSTR_INVALID_ENC:
821 hw_error_status.js_status[job_slot] =
822 JS_STATUS_INSTR_INVALID_ENC;
823 break;
824
825 case KBASE_INSTR_TYPE_MISMATCH:
826 hw_error_status.js_status[job_slot] =
827 JS_STATUS_INSTR_TYPE_MISMATCH;
828 break;
829
830 case KBASE_INSTR_OPERAND_FAULT:
831 hw_error_status.js_status[job_slot] =
832 JS_STATUS_INSTR_OPERAND_FAULT;
833 break;
834
835 case KBASE_INSTR_TLS_FAULT:
836 hw_error_status.js_status[job_slot] =
837 JS_STATUS_INSTR_TLS_FAULT;
838 break;
839
840 case KBASE_INSTR_BARRIER_FAULT:
841 hw_error_status.js_status[job_slot] =
842 JS_STATUS_INSTR_BARRIER_FAULT;
843 break;
844
845 case KBASE_INSTR_ALIGN_FAULT:
846 hw_error_status.js_status[job_slot] =
847 JS_STATUS_INSTR_ALIGN_FAULT;
848 break;
849
850 case KBASE_DATA_INVALID_FAULT:
851 hw_error_status.js_status[job_slot] =
852 JS_STATUS_DATA_INVALID_FAULT;
853 break;
854
855 case KBASE_TILE_RANGE_FAULT:
856 hw_error_status.js_status[job_slot] =
857 JS_STATUS_TILE_RANGE_FAULT;
858 break;
859
860 case KBASE_ADDR_RANGE_FAULT:
861 hw_error_status.js_status[job_slot] =
862 JS_STATUS_ADDRESS_RANGE_FAULT;
863 break;
864
865 case KBASE_OUT_OF_MEMORY:
866 hw_error_status.js_status[job_slot] =
867 JS_STATUS_OUT_OF_MEMORY;
868 break;
869
870 case KBASE_UNKNOWN:
871 hw_error_status.js_status[job_slot] =
872 JS_STATUS_UNKNOWN;
873 break;
874
875 default:
876 model_error_log(KBASE_CORE,
877 "\nAtom Chain 0x%llx: Invalid Error Mask!",
878 hw_error_status.current_jc);
879 break;
880 }
881 }
882 #endif /* !MALI_USE_CSF */
883
884 /* we set JOB_FAIL_<n> */
885 hw_error_status.job_irq_rawstat |=
886 (dummy->slots[job_slot].job_complete_irq_asserted) <<
887 (job_slot + 16);
888 hw_error_status.job_irq_status |=
889 (((dummy->slots[job_slot].job_complete_irq_asserted) <<
890 (job_slot)) &
891 (dummy->slots[job_slot].job_irq_mask <<
892 job_slot)) << 16;
893 } else {
894 hw_error_status.job_irq_rawstat |=
895 (dummy->slots[job_slot].job_complete_irq_asserted) <<
896 job_slot;
897 hw_error_status.job_irq_status |=
898 ((dummy->slots[job_slot].job_complete_irq_asserted) <<
899 (job_slot)) &
900 (dummy->slots[job_slot].job_irq_mask <<
901 job_slot);
902 }
903 } else {
904 hw_error_status.job_irq_rawstat |=
905 (dummy->slots[job_slot].job_complete_irq_asserted) <<
906 job_slot;
907 hw_error_status.job_irq_status |=
908 ((dummy->slots[job_slot].job_complete_irq_asserted) <<
909 (job_slot)) &
910 (dummy->slots[job_slot].job_irq_mask << job_slot);
911 } /* end of job register statuses */
912
913 if (hw_error_status.errors_mask & IS_A_MMU_ERROR) {
914 int i;
915
916 for (i = 0; i < NUM_MMU_AS; i++) {
917 if (i == hw_error_status.faulty_mmu_as) {
918 if (hw_error_status.as_faultstatus[i] == 0) {
919 u32 status =
920 hw_error_status.as_faultstatus[i];
921 /* status reg is clean; it can be
922 * written
923 */
924 switch (hw_error_status.errors_mask &
925 IS_A_MMU_ERROR) {
926 case KBASE_TRANSLATION_FAULT:
927 /* 0xCm means TRANSLATION FAULT
928 * (m is mmu_table_level)
929 */
930 status =
931 ((1 << 7) | (1 << 6) |
932 hw_error_status.mmu_table_level
933 );
934 break;
935
936 case KBASE_PERMISSION_FAULT:
937 /*0xC8 means PERMISSION FAULT */
938 status = ((1 << 7) | (1 << 6) |
939 (1 << 3));
940 break;
941
942 case KBASE_TRANSTAB_BUS_FAULT:
943 /* 0xDm means TRANSITION TABLE
944 * BUS FAULT (m is
945 * mmu_table_level)
946 */
947 status = ((1 << 7) | (1 << 6) |
948 (1 << 4) |
949 hw_error_status.mmu_table_level
950 );
951 break;
952
953 case KBASE_ACCESS_FLAG:
954 /* 0xD8 means ACCESS FLAG */
955 status = ((1 << 7) | (1 << 6) |
956 (1 << 4) | (1 << 3));
957 break;
958
959 default:
960 model_error_log(KBASE_CORE,
961 "\nAtom Chain 0x%llx: Invalid Error Mask!",
962 hw_error_status.current_jc);
963 break;
964 }
965 hw_error_status.as_faultstatus[i] =
966 status;
967 }
968
969 if (hw_error_status.errors_mask &
970 KBASE_TRANSTAB_BUS_FAULT)
971 hw_error_status.mmu_irq_rawstat |=
972 1 << (16 + i); /* bus error */
973 else
974 hw_error_status.mmu_irq_rawstat |=
975 1 << i; /* page fault */
976 }
977 }
978 } /*end of mmu register statuses */
979 if (hw_error_status.errors_mask & IS_A_GPU_ERROR) {
980 if (hw_error_status.gpu_fault_status) {
981 /* not the first GPU error reported */
982 hw_error_status.gpu_error_irq |= (1 << 7);
983 } else {
984 hw_error_status.gpu_error_irq |= 1;
985 switch (hw_error_status.errors_mask & IS_A_GPU_ERROR) {
986 case KBASE_DELAYED_BUS_FAULT:
987 hw_error_status.gpu_fault_status = (1 << 7);
988 break;
989
990 case KBASE_SHAREABILITY_FAULT:
991 hw_error_status.gpu_fault_status = (1 << 7) |
992 (1 << 3);
993 break;
994
995 default:
996 model_error_log(KBASE_CORE,
997 "\nAtom Chain 0x%llx: Invalid Error Mask!",
998 hw_error_status.current_jc);
999 break;
1000 }
1001 }
1002 }
1003 hw_error_status.errors_mask = 0; /*clear error mask */
1004 }
1005
1006 #if !MALI_USE_CSF
update_job_irq_js_state(struct dummy_model_t * dummy,int mask)1007 static void update_job_irq_js_state(struct dummy_model_t *dummy, int mask)
1008 {
1009 int i;
1010
1011 lockdep_assert_held(&hw_error_status.access_lock);
1012 pr_debug("%s", "Updating the JS_ACTIVE register");
1013
1014 for (i = 0; i < NUM_SLOTS; i++) {
1015 int slot_active = dummy->slots[i].job_active;
1016 int next_busy = dummy->slots[i].job_queued;
1017
1018 if ((mask & (1 << i)) || (mask & (1 << (i + 16)))) {
1019 /* clear the bits we're updating */
1020 dummy->job_irq_js_state &= ~((1 << (16 + i)) |
1021 (1 << i));
1022 if (hw_error_status.js_status[i]) {
1023 dummy->job_irq_js_state |= next_busy <<
1024 (i + 16);
1025 if (mask & (1 << (i + 16))) {
1026 /* clear job slot status */
1027 hw_error_status.js_status[i] = 0;
1028 /* continue execution of jobchain */
1029 dummy->slots[i].job_active =
1030 dummy->slots[i].job_queued;
1031 }
1032 } else {
1033 /* set bits if needed */
1034 dummy->job_irq_js_state |= ((slot_active << i) |
1035 (next_busy << (i + 16)));
1036 }
1037 }
1038 }
1039 pr_debug("The new snapshot is 0x%08X\n", dummy->job_irq_js_state);
1040 }
1041 #endif /* !MALI_USE_CSF */
1042
1043 /**
1044 * find_control_reg_values() - Look up constant control register values.
1045 * @gpu: GPU name
1046 *
1047 * Look up the GPU name to find the correct set of control register values for
1048 * that GPU. If not found, warn and use the first values in the array.
1049 *
1050 * Return: Pointer to control register values for that GPU.
1051 */
find_control_reg_values(const char * gpu)1052 static const struct control_reg_values_t *find_control_reg_values(const char *gpu)
1053 {
1054 size_t i;
1055 const struct control_reg_values_t *ret = NULL;
1056
1057 /* Edge case for tGOx, as it has 2 entries in the table for its R0 and R1
1058 * revisions respectively. As none of them are named "tGOx" the name comparison
1059 * needs to be fixed in these cases. CONFIG_GPU_HWVER should be one of "r0p0"
1060 * or "r1p0" and is derived from the DDK's build configuration. In cases
1061 * where it is unavailable, it defaults to tGOx r1p0.
1062 */
1063 if (!strcmp(gpu, "tGOx")) {
1064 #ifdef CONFIG_GPU_HWVER
1065 if (!strcmp(CONFIG_GPU_HWVER, "r0p0"))
1066 gpu = "tGOx_r0p0";
1067 else if (!strcmp(CONFIG_GPU_HWVER, "r1p0"))
1068 #endif /* CONFIG_GPU_HWVER defined */
1069 gpu = "tGOx_r1p0";
1070 }
1071
1072 for (i = 0; i < ARRAY_SIZE(all_control_reg_values); ++i) {
1073 const struct control_reg_values_t * const fcrv = &all_control_reg_values[i];
1074
1075 if (!strcmp(fcrv->name, gpu)) {
1076 ret = fcrv;
1077 pr_debug("Found control register values for %s\n", gpu);
1078 break;
1079 }
1080 }
1081
1082 if (!ret) {
1083 ret = &all_control_reg_values[0];
1084 pr_warn("Couldn't find control register values for GPU %s; using default %s\n",
1085 gpu, ret->name);
1086 }
1087
1088 return ret;
1089 }
1090
midgard_model_create(struct kbase_device * kbdev)1091 void *midgard_model_create(struct kbase_device *kbdev)
1092 {
1093 struct dummy_model_t *dummy = NULL;
1094
1095 spin_lock_init(&hw_error_status.access_lock);
1096 spin_lock_init(&performance_counters.access_lock);
1097
1098 dummy = kzalloc(sizeof(*dummy), GFP_KERNEL);
1099
1100 if (dummy) {
1101 dummy->job_irq_js_state = 0;
1102 init_register_statuses(dummy);
1103 dummy->control_reg_values = find_control_reg_values(no_mali_gpu);
1104 performance_counters.l2_present = get_implementation_register(
1105 GPU_CONTROL_REG(L2_PRESENT_LO), dummy->control_reg_values);
1106 performance_counters.shader_present = get_implementation_register(
1107 GPU_CONTROL_REG(SHADER_PRESENT_LO), dummy->control_reg_values);
1108
1109 gpu_device_set_data(dummy, kbdev);
1110
1111 dev_info(kbdev->dev, "Using Dummy Model");
1112 }
1113
1114 return dummy;
1115 }
1116
midgard_model_destroy(void * h)1117 void midgard_model_destroy(void *h)
1118 {
1119 kfree((void *)h);
1120 }
1121
midgard_model_get_outputs(void * h)1122 static void midgard_model_get_outputs(void *h)
1123 {
1124 struct dummy_model_t *dummy = (struct dummy_model_t *)h;
1125
1126 lockdep_assert_held(&hw_error_status.access_lock);
1127
1128 if (hw_error_status.job_irq_status)
1129 gpu_device_raise_irq(dummy, MODEL_LINUX_JOB_IRQ);
1130
1131 if ((dummy->power_changed && dummy->power_changed_mask) ||
1132 (dummy->reset_completed & dummy->reset_completed_mask) ||
1133 hw_error_status.gpu_error_irq ||
1134 #if !MALI_USE_CSF
1135 dummy->prfcnt_sample_completed ||
1136 #else
1137 (dummy->flush_pa_range_completed && dummy->flush_pa_range_completed_irq_enabled) ||
1138 #endif
1139 (dummy->clean_caches_completed && dummy->clean_caches_completed_irq_enabled))
1140 gpu_device_raise_irq(dummy, MODEL_LINUX_GPU_IRQ);
1141
1142 if (hw_error_status.mmu_irq_rawstat & hw_error_status.mmu_irq_mask)
1143 gpu_device_raise_irq(dummy, MODEL_LINUX_MMU_IRQ);
1144 }
1145
midgard_model_update(void * h)1146 static void midgard_model_update(void *h)
1147 {
1148 struct dummy_model_t *dummy = (struct dummy_model_t *)h;
1149 int i;
1150
1151 lockdep_assert_held(&hw_error_status.access_lock);
1152
1153 for (i = 0; i < NUM_SLOTS; i++) {
1154 if (!dummy->slots[i].job_active)
1155 continue;
1156
1157 if (dummy->slots[i].job_disabled) {
1158 update_register_statuses(dummy, i);
1159 continue;
1160 }
1161
1162 /* If there are any pending interrupts that have not
1163 * been cleared we cannot run the job in the next register
1164 * as we will overwrite the register status of the job in
1165 * the head registers - which has not yet been read
1166 */
1167 if ((hw_error_status.job_irq_rawstat & (1 << (i + 16))) ||
1168 (hw_error_status.job_irq_rawstat & (1 << i))) {
1169 continue;
1170 }
1171
1172 /*this job is done assert IRQ lines */
1173 signal_int(dummy, i);
1174 #ifdef CONFIG_MALI_BIFROST_ERROR_INJECT
1175 midgard_set_error(i);
1176 #endif /* CONFIG_MALI_BIFROST_ERROR_INJECT */
1177 update_register_statuses(dummy, i);
1178 /*if this job slot returned failures we cannot use it */
1179 if (hw_error_status.job_irq_rawstat & (1 << (i + 16))) {
1180 dummy->slots[i].job_active = 0;
1181 continue;
1182 }
1183 /*process next job */
1184 dummy->slots[i].job_active = dummy->slots[i].job_queued;
1185 dummy->slots[i].job_queued = 0;
1186 if (dummy->slots[i].job_active) {
1187 if (hw_error_status.job_irq_rawstat & (1 << (i + 16)))
1188 model_error_log(KBASE_CORE,
1189 "\natom %lld running a job on a dirty slot",
1190 hw_error_status.current_jc);
1191 }
1192 }
1193 }
1194
invalidate_active_jobs(struct dummy_model_t * dummy)1195 static void invalidate_active_jobs(struct dummy_model_t *dummy)
1196 {
1197 int i;
1198
1199 lockdep_assert_held(&hw_error_status.access_lock);
1200
1201 for (i = 0; i < NUM_SLOTS; i++) {
1202 if (dummy->slots[i].job_active) {
1203 hw_error_status.job_irq_rawstat |= (1 << (16 + i));
1204
1205 hw_error_status.js_status[i] = 0x7f; /*UNKNOWN*/
1206 }
1207 }
1208 }
1209
midgard_model_write_reg(void * h,u32 addr,u32 value)1210 void midgard_model_write_reg(void *h, u32 addr, u32 value)
1211 {
1212 unsigned long flags;
1213 struct dummy_model_t *dummy = (struct dummy_model_t *)h;
1214
1215 spin_lock_irqsave(&hw_error_status.access_lock, flags);
1216
1217 #if !MALI_USE_CSF
1218 if ((addr >= JOB_CONTROL_REG(JOB_SLOT0)) &&
1219 (addr < (JOB_CONTROL_REG(JOB_SLOT15) + 0x80))) {
1220 unsigned int slot_idx = (addr >> 7) & 0xf;
1221
1222 KBASE_DEBUG_ASSERT(slot_idx < NUM_SLOTS);
1223 if (addr == JOB_SLOT_REG(slot_idx, JS_HEAD_NEXT_LO)) {
1224 hw_error_status.current_jc &=
1225 ~((u64) (0xFFFFFFFF));
1226 hw_error_status.current_jc |= (u64) value;
1227 }
1228 if (addr == JOB_SLOT_REG(slot_idx, JS_HEAD_NEXT_HI)) {
1229 hw_error_status.current_jc &= (u64) 0xFFFFFFFF;
1230 hw_error_status.current_jc |=
1231 ((u64) value) << 32;
1232 }
1233 if (addr == JOB_SLOT_REG(slot_idx, JS_COMMAND_NEXT) &&
1234 value == 1) {
1235 pr_debug("%s", "start detected");
1236 KBASE_DEBUG_ASSERT(!dummy->slots[slot_idx].job_active ||
1237 !dummy->slots[slot_idx].job_queued);
1238 if ((dummy->slots[slot_idx].job_active) ||
1239 (hw_error_status.job_irq_rawstat &
1240 (1 << (slot_idx + 16)))) {
1241 pr_debug("~~~~~~~~~~~ Start: job slot is already active or there are IRQ pending ~~~~~~~~~"
1242 );
1243 dummy->slots[slot_idx].job_queued = 1;
1244 } else {
1245 dummy->slots[slot_idx].job_active = 1;
1246 }
1247 }
1248
1249 if (addr == JOB_SLOT_REG(slot_idx, JS_COMMAND_NEXT) && value ==
1250 0)
1251 dummy->slots[slot_idx].job_queued = 0;
1252
1253 if ((addr == JOB_SLOT_REG(slot_idx, JS_COMMAND)) &&
1254 (value == JS_COMMAND_SOFT_STOP ||
1255 value == JS_COMMAND_HARD_STOP)) {
1256 /*dummy->slots[slot_idx].job_active = 0; */
1257 hw_error_status.current_job_slot = slot_idx;
1258 if (value == JS_COMMAND_SOFT_STOP) {
1259 hw_error_status.errors_mask = KBASE_JOB_STOPPED;
1260 } else { /*value == 3 */
1261
1262 if (dummy->slots[slot_idx].job_disabled != 0) {
1263 pr_debug("enabling slot after HARD_STOP"
1264 );
1265 dummy->slots[slot_idx].job_disabled = 0;
1266 }
1267 hw_error_status.errors_mask =
1268 KBASE_JOB_TERMINATED;
1269 }
1270 }
1271 } else if (addr == JOB_CONTROL_REG(JOB_IRQ_CLEAR)) {
1272 int i;
1273
1274 for (i = 0; i < NUM_SLOTS; i++) {
1275 if (value & ((1 << i) | (1 << (i + 16))))
1276 dummy->slots[i].job_complete_irq_asserted = 0;
1277 /* hw_error_status.js_status[i] is cleared in
1278 * update_job_irq_js_state
1279 */
1280 }
1281 pr_debug("%s", "job irq cleared");
1282 update_job_irq_js_state(dummy, value);
1283 /*remove error condition for JOB */
1284 hw_error_status.job_irq_rawstat &= ~(value);
1285 hw_error_status.job_irq_status &= ~(value);
1286 } else if (addr == JOB_CONTROL_REG(JOB_IRQ_MASK)) {
1287 int i;
1288
1289 for (i = 0; i < NUM_SLOTS; i++)
1290 dummy->slots[i].job_irq_mask = (value >> i) & 0x01;
1291 pr_debug("job irq mask to value %x", value);
1292 } else if (addr == GPU_CONTROL_REG(GPU_IRQ_MASK)) {
1293 #else /* !MALI_USE_CSF */
1294 if (addr == JOB_CONTROL_REG(JOB_IRQ_CLEAR)) {
1295 pr_debug("%s", "job irq cleared");
1296
1297 hw_error_status.job_irq_rawstat &= ~(value);
1298 hw_error_status.job_irq_status &= ~(value);
1299 } else if (addr == JOB_CONTROL_REG(JOB_IRQ_MASK)) {
1300 /* ignore JOB_IRQ_MASK as it is handled by CSFFW */
1301 } else if (addr == GPU_CONTROL_REG(GPU_IRQ_MASK)) {
1302 #endif /* !MALI_USE_CSF */
1303 pr_debug("GPU_IRQ_MASK set to 0x%x", value);
1304 dummy->reset_completed_mask = (value >> 8) & 0x01;
1305 dummy->power_changed_mask = (value >> 9) & 0x03;
1306 dummy->clean_caches_completed_irq_enabled = (value & (1u << 17)) != 0u;
1307 #if MALI_USE_CSF
1308 dummy->flush_pa_range_completed_irq_enabled = (value & (1u << 20)) != 0u;
1309 #endif
1310 } else if (addr == GPU_CONTROL_REG(COHERENCY_ENABLE)) {
1311 dummy->coherency_enable = value;
1312 } else if (addr == GPU_CONTROL_REG(GPU_IRQ_CLEAR)) {
1313 if (value & (1 << 8)) {
1314 pr_debug("%s", "gpu RESET_COMPLETED irq cleared");
1315 dummy->reset_completed = 0;
1316 }
1317 if (value & (3 << 9))
1318 dummy->power_changed = 0;
1319
1320 if (value & (1 << 17))
1321 dummy->clean_caches_completed = false;
1322
1323 #if MALI_USE_CSF
1324 if (value & (1u << 20))
1325 dummy->flush_pa_range_completed = false;
1326 #endif /* MALI_USE_CSF */
1327
1328 #if !MALI_USE_CSF
1329 if (value & PRFCNT_SAMPLE_COMPLETED) /* (1 << 16) */
1330 dummy->prfcnt_sample_completed = 0;
1331 #endif /* !MALI_USE_CSF */
1332
1333 /*update error status */
1334 hw_error_status.gpu_error_irq &= ~(value);
1335 } else if (addr == GPU_CONTROL_REG(GPU_COMMAND)) {
1336 switch (value) {
1337 case GPU_COMMAND_SOFT_RESET:
1338 case GPU_COMMAND_HARD_RESET:
1339 pr_debug("gpu reset (%d) requested", value);
1340 /* no more fault status */
1341 hw_error_status.gpu_fault_status = 0;
1342 /* completed reset instantly */
1343 dummy->reset_completed = 1;
1344 break;
1345 #if MALI_USE_CSF
1346 case GPU_COMMAND_CACHE_CLN_INV_L2:
1347 case GPU_COMMAND_CACHE_CLN_INV_L2_LSC:
1348 case GPU_COMMAND_CACHE_CLN_INV_FULL:
1349 #else
1350 case GPU_COMMAND_CLEAN_CACHES:
1351 case GPU_COMMAND_CLEAN_INV_CACHES:
1352 #endif
1353 pr_debug("clean caches requested");
1354 dummy->clean_caches_completed = true;
1355 break;
1356 #if MALI_USE_CSF
1357 case GPU_COMMAND_FLUSH_PA_RANGE_CLN_INV_L2:
1358 case GPU_COMMAND_FLUSH_PA_RANGE_CLN_INV_L2_LSC:
1359 case GPU_COMMAND_FLUSH_PA_RANGE_CLN_INV_FULL:
1360 pr_debug("pa range flush requested");
1361 dummy->flush_pa_range_completed = true;
1362 break;
1363 #endif /* MALI_USE_CSF */
1364 #if !MALI_USE_CSF
1365 case GPU_COMMAND_PRFCNT_SAMPLE:
1366 midgard_model_dump_prfcnt();
1367 dummy->prfcnt_sample_completed = 1;
1368 #endif /* !MALI_USE_CSF */
1369 default:
1370 break;
1371 }
1372 #if MALI_USE_CSF
1373 } else if (addr >= GPU_CONTROL_REG(GPU_COMMAND_ARG0_LO) &&
1374 addr <= GPU_CONTROL_REG(GPU_COMMAND_ARG1_HI)) {
1375 /* Writes ignored */
1376 #endif
1377 } else if (addr == GPU_CONTROL_REG(L2_CONFIG)) {
1378 dummy->l2_config = value;
1379 }
1380 #if MALI_USE_CSF
1381 else if (addr >= GPU_CONTROL_REG(CSF_HW_DOORBELL_PAGE_OFFSET) &&
1382 addr < GPU_CONTROL_REG(CSF_HW_DOORBELL_PAGE_OFFSET +
1383 (CSF_NUM_DOORBELL * CSF_HW_DOORBELL_PAGE_SIZE))) {
1384 if (addr == GPU_CONTROL_REG(CSF_HW_DOORBELL_PAGE_OFFSET))
1385 hw_error_status.job_irq_status = JOB_IRQ_GLOBAL_IF;
1386 } else if ((addr >= GPU_CONTROL_REG(SYSC_ALLOC0)) &&
1387 (addr < GPU_CONTROL_REG(SYSC_ALLOC(SYSC_ALLOC_COUNT)))) {
1388 /* Do nothing */
1389 } else if ((addr >= GPU_CONTROL_REG(ASN_HASH_0)) &&
1390 (addr < GPU_CONTROL_REG(ASN_HASH(ASN_HASH_COUNT)))) {
1391 /* Do nothing */
1392 } else if (addr == IPA_CONTROL_REG(COMMAND)) {
1393 pr_debug("Received IPA_CONTROL command");
1394 } else if (addr == IPA_CONTROL_REG(TIMER)) {
1395 ipa_control_timer_enabled = value ? true : false;
1396 } else if ((addr >= IPA_CONTROL_REG(SELECT_CSHW_LO)) &&
1397 (addr <= IPA_CONTROL_REG(SELECT_SHADER_HI))) {
1398 enum kbase_ipa_core_type core_type = (enum kbase_ipa_core_type)(
1399 (addr - IPA_CONTROL_REG(SELECT_CSHW_LO)) >> 3);
1400 bool is_low_word =
1401 !((addr - IPA_CONTROL_REG(SELECT_CSHW_LO)) & 7);
1402
1403 if (is_low_word) {
1404 ipa_ctl_select_config[core_type] &= ~(u64)U32_MAX;
1405 ipa_ctl_select_config[core_type] |= value;
1406 } else {
1407 ipa_ctl_select_config[core_type] &= U32_MAX;
1408 ipa_ctl_select_config[core_type] |= ((u64)value << 32);
1409 }
1410 }
1411 #endif
1412 else if (addr == MMU_REG(MMU_IRQ_MASK)) {
1413 hw_error_status.mmu_irq_mask = value;
1414 } else if (addr == MMU_REG(MMU_IRQ_CLEAR)) {
1415 hw_error_status.mmu_irq_rawstat &= (~value);
1416 } else if ((addr >= MMU_AS_REG(0, AS_TRANSTAB_LO)) && (addr <= MMU_AS_REG(15, AS_STATUS))) {
1417 int mem_addr_space = (addr - MMU_AS_REG(0, AS_TRANSTAB_LO))
1418 >> 6;
1419
1420 switch (addr & 0x3F) {
1421 case AS_COMMAND:
1422 switch (value) {
1423 case AS_COMMAND_NOP:
1424 hw_error_status.as_command[mem_addr_space] =
1425 value;
1426 break;
1427
1428 case AS_COMMAND_UPDATE:
1429 hw_error_status.as_command[mem_addr_space] =
1430 value;
1431 if ((hw_error_status.as_faultstatus[
1432 mem_addr_space])
1433 && ((hw_error_status.as_transtab[
1434 mem_addr_space] & 0x3) != 0)) {
1435 model_error_log(KBASE_CORE,
1436 "\n ERROR: AS_COMMAND issued UPDATE on error condition before AS_TRANSTAB been set to unmapped\n"
1437 );
1438 } else if ((hw_error_status.as_faultstatus[
1439 mem_addr_space])
1440 && ((hw_error_status.as_transtab[
1441 mem_addr_space] & 0x3) == 0)) {
1442
1443 /*invalidate all active jobs */
1444 invalidate_active_jobs(dummy);
1445 /* error handled */
1446 hw_error_status.as_faultstatus[
1447 mem_addr_space] = 0;
1448 }
1449 break;
1450
1451 case AS_COMMAND_LOCK:
1452 case AS_COMMAND_UNLOCK:
1453 hw_error_status.as_command[mem_addr_space] =
1454 value;
1455 break;
1456
1457 case AS_COMMAND_FLUSH_PT:
1458 case AS_COMMAND_FLUSH_MEM:
1459 if (hw_error_status.as_command[mem_addr_space]
1460 != AS_COMMAND_LOCK)
1461 model_error_log(KBASE_CORE,
1462 "\n ERROR: AS_COMMAND issued FLUSH without LOCKING before\n"
1463 );
1464 else /* error handled if any */
1465 hw_error_status.as_faultstatus[
1466 mem_addr_space] = 0;
1467 hw_error_status.as_command[mem_addr_space] =
1468 value;
1469 break;
1470
1471 default:
1472 model_error_log(KBASE_CORE,
1473 "\n WARNING: UNRECOGNIZED AS_COMMAND 0x%x\n",
1474 value);
1475 break;
1476 }
1477 break;
1478
1479 case AS_TRANSTAB_LO:
1480 hw_error_status.as_transtab[mem_addr_space] &=
1481 ~((u64) (0xffffffff));
1482 hw_error_status.as_transtab[mem_addr_space] |=
1483 (u64) value;
1484 break;
1485
1486 case AS_TRANSTAB_HI:
1487 hw_error_status.as_transtab[mem_addr_space] &=
1488 (u64) 0xffffffff;
1489 hw_error_status.as_transtab[mem_addr_space] |=
1490 ((u64) value) << 32;
1491 break;
1492
1493 case AS_LOCKADDR_LO:
1494 case AS_LOCKADDR_HI:
1495 case AS_MEMATTR_LO:
1496 case AS_MEMATTR_HI:
1497 case AS_TRANSCFG_LO:
1498 case AS_TRANSCFG_HI:
1499 /* Writes ignored */
1500 break;
1501
1502 default:
1503 model_error_log(KBASE_CORE,
1504 "Dummy model register access: Writing unsupported MMU #%d register 0x%x value 0x%x\n",
1505 mem_addr_space, addr, value);
1506 break;
1507 }
1508 } else {
1509 switch (addr) {
1510 #if !MALI_USE_CSF
1511 case PRFCNT_BASE_LO:
1512 performance_counters.prfcnt_base =
1513 HI_MASK(performance_counters.prfcnt_base) | value;
1514 performance_counters.prfcnt_base_cpu =
1515 (u32 *)(uintptr_t)performance_counters.prfcnt_base;
1516 break;
1517 case PRFCNT_BASE_HI:
1518 performance_counters.prfcnt_base =
1519 LO_MASK(performance_counters.prfcnt_base) | (((u64)value) << 32);
1520 performance_counters.prfcnt_base_cpu =
1521 (u32 *)(uintptr_t)performance_counters.prfcnt_base;
1522 break;
1523 case PRFCNT_JM_EN:
1524 performance_counters.prfcnt_en.fe = value;
1525 break;
1526 case PRFCNT_SHADER_EN:
1527 performance_counters.prfcnt_en.shader = value;
1528 break;
1529 case PRFCNT_TILER_EN:
1530 performance_counters.prfcnt_en.tiler = value;
1531 break;
1532 case PRFCNT_MMU_L2_EN:
1533 performance_counters.prfcnt_en.l2 = value;
1534 break;
1535 #endif /* !MALI_USE_CSF */
1536 case TILER_PWRON_LO:
1537 dummy->power_on |= (value & 1) << 1;
1538 /* Also ensure L2 is powered on */
1539 dummy->power_on |= value & 1;
1540 dummy->power_changed = 1;
1541 break;
1542 case SHADER_PWRON_LO:
1543 dummy->power_on |=
1544 (value & dummy->control_reg_values->shader_present) << 2;
1545 dummy->power_changed = 1;
1546 break;
1547 case L2_PWRON_LO:
1548 dummy->power_on |= value & 1;
1549 dummy->power_changed = 1;
1550 break;
1551 case STACK_PWRON_LO:
1552 dummy->stack_power_on_lo |= value;
1553 dummy->power_changed = 1;
1554 break;
1555 case TILER_PWROFF_LO:
1556 dummy->power_on &= ~((value & 1) << 1);
1557 dummy->power_changed = 1;
1558 break;
1559 case SHADER_PWROFF_LO:
1560 dummy->power_on &=
1561 ~((value & dummy->control_reg_values->shader_present) << 2);
1562 dummy->power_changed = 1;
1563 break;
1564 case L2_PWROFF_LO:
1565 dummy->power_on &= ~(value & 1);
1566 /* Also ensure tiler is powered off */
1567 dummy->power_on &= ~((value & 1) << 1);
1568 dummy->power_changed = 1;
1569 break;
1570 case STACK_PWROFF_LO:
1571 dummy->stack_power_on_lo &= ~value;
1572 dummy->power_changed = 1;
1573 break;
1574
1575 case TILER_PWROFF_HI:
1576 case SHADER_PWROFF_HI:
1577 case L2_PWROFF_HI:
1578 case PWR_KEY:
1579 case PWR_OVERRIDE0:
1580 #if !MALI_USE_CSF
1581 case JM_CONFIG:
1582 case PRFCNT_CONFIG:
1583 #else /* !MALI_USE_CSF */
1584 case CSF_CONFIG:
1585 #endif /* !MALI_USE_CSF */
1586 case SHADER_CONFIG:
1587 case TILER_CONFIG:
1588 case L2_MMU_CONFIG:
1589 /* Writes ignored */
1590 break;
1591 default:
1592 model_error_log(KBASE_CORE,
1593 "Dummy model register access: Writing unsupported register 0x%x value 0x%x\n",
1594 addr, value);
1595 break;
1596 }
1597 }
1598
1599 midgard_model_update(dummy);
1600 midgard_model_get_outputs(dummy);
1601 spin_unlock_irqrestore(&hw_error_status.access_lock, flags);
1602 }
1603
1604 void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
1605 {
1606 unsigned long flags;
1607 struct dummy_model_t *dummy = (struct dummy_model_t *)h;
1608
1609 spin_lock_irqsave(&hw_error_status.access_lock, flags);
1610
1611 *value = 0; /* 0 by default */
1612 #if !MALI_USE_CSF
1613 if (addr == JOB_CONTROL_REG(JOB_IRQ_JS_STATE)) {
1614 pr_debug("%s", "JS_ACTIVE being read");
1615
1616 *value = dummy->job_irq_js_state;
1617 } else if (addr == GPU_CONTROL_REG(GPU_ID)) {
1618 #else /* !MALI_USE_CSF */
1619 if (addr == GPU_CONTROL_REG(GPU_ID)) {
1620 #endif /* !MALI_USE_CSF */
1621
1622 *value = dummy->control_reg_values->gpu_id;
1623 } else if (addr == JOB_CONTROL_REG(JOB_IRQ_RAWSTAT)) {
1624 *value = hw_error_status.job_irq_rawstat;
1625 pr_debug("%s", "JS_IRQ_RAWSTAT being read");
1626 } else if (addr == JOB_CONTROL_REG(JOB_IRQ_STATUS)) {
1627 *value = hw_error_status.job_irq_status;
1628 pr_debug("JS_IRQ_STATUS being read %x", *value);
1629 }
1630 #if !MALI_USE_CSF
1631 else if (addr == JOB_CONTROL_REG(JOB_IRQ_MASK)) {
1632 int i;
1633
1634 *value = 0;
1635 for (i = 0; i < NUM_SLOTS; i++)
1636 *value |= dummy->slots[i].job_irq_mask << i;
1637 pr_debug("JS_IRQ_MASK being read %x", *value);
1638 }
1639 #else /* !MALI_USE_CSF */
1640 else if (addr == JOB_CONTROL_REG(JOB_IRQ_MASK))
1641 ; /* ignore JOB_IRQ_MASK as it is handled by CSFFW */
1642 #endif /* !MALI_USE_CSF */
1643 else if (addr == GPU_CONTROL_REG(GPU_IRQ_MASK)) {
1644 *value = (dummy->reset_completed_mask << 8) |
1645 ((dummy->clean_caches_completed_irq_enabled ? 1u : 0u) << 17) |
1646 #if MALI_USE_CSF
1647 ((dummy->flush_pa_range_completed_irq_enabled ? 1u : 0u) << 20) |
1648 #endif
1649 (dummy->power_changed_mask << 9) | (1 << 7) | 1;
1650 pr_debug("GPU_IRQ_MASK read %x", *value);
1651 } else if (addr == GPU_CONTROL_REG(GPU_IRQ_RAWSTAT)) {
1652 *value = (dummy->power_changed << 9) | (dummy->power_changed << 10) |
1653 (dummy->reset_completed << 8) |
1654 #if !MALI_USE_CSF
1655 (dummy->prfcnt_sample_completed ? PRFCNT_SAMPLE_COMPLETED : 0) |
1656 #endif /* !MALI_USE_CSF */
1657 ((dummy->clean_caches_completed ? 1u : 0u) << 17) |
1658 #if MALI_USE_CSF
1659 ((dummy->flush_pa_range_completed ? 1u : 0u) << 20) |
1660 #endif
1661 hw_error_status.gpu_error_irq;
1662 pr_debug("GPU_IRQ_RAWSTAT read %x", *value);
1663 } else if (addr == GPU_CONTROL_REG(GPU_IRQ_STATUS)) {
1664 *value = ((dummy->power_changed && (dummy->power_changed_mask & 0x1)) << 9) |
1665 ((dummy->power_changed && (dummy->power_changed_mask & 0x2)) << 10) |
1666 ((dummy->reset_completed & dummy->reset_completed_mask) << 8) |
1667 #if !MALI_USE_CSF
1668 (dummy->prfcnt_sample_completed ? PRFCNT_SAMPLE_COMPLETED : 0) |
1669 #endif /* !MALI_USE_CSF */
1670 (((dummy->clean_caches_completed &&
1671 dummy->clean_caches_completed_irq_enabled) ?
1672 1u :
1673 0u)
1674 << 17) |
1675 #if MALI_USE_CSF
1676 (((dummy->flush_pa_range_completed &&
1677 dummy->flush_pa_range_completed_irq_enabled) ?
1678 1u :
1679 0u)
1680 << 20) |
1681 #endif
1682 hw_error_status.gpu_error_irq;
1683 pr_debug("GPU_IRQ_STAT read %x", *value);
1684 } else if (addr == GPU_CONTROL_REG(GPU_STATUS)) {
1685 *value = 0;
1686 #if !MALI_USE_CSF
1687 } else if (addr == GPU_CONTROL_REG(LATEST_FLUSH)) {
1688 *value = 0;
1689 #endif
1690 } else if (addr == GPU_CONTROL_REG(GPU_FAULTSTATUS)) {
1691 *value = hw_error_status.gpu_fault_status;
1692 } else if (addr == GPU_CONTROL_REG(L2_CONFIG)) {
1693 *value = dummy->l2_config;
1694 }
1695 #if MALI_USE_CSF
1696 else if ((addr >= GPU_CONTROL_REG(SYSC_ALLOC0)) &&
1697 (addr < GPU_CONTROL_REG(SYSC_ALLOC(SYSC_ALLOC_COUNT)))) {
1698 *value = 0;
1699 } else if ((addr >= GPU_CONTROL_REG(ASN_HASH_0)) &&
1700 (addr < GPU_CONTROL_REG(ASN_HASH(ASN_HASH_COUNT)))) {
1701 *value = 0;
1702 }
1703 #endif
1704 else if ((addr >= GPU_CONTROL_REG(SHADER_PRESENT_LO)) &&
1705 (addr <= GPU_CONTROL_REG(L2_MMU_CONFIG))) {
1706 switch (addr) {
1707 case GPU_CONTROL_REG(SHADER_PRESENT_LO):
1708 case GPU_CONTROL_REG(SHADER_PRESENT_HI):
1709 case GPU_CONTROL_REG(TILER_PRESENT_LO):
1710 case GPU_CONTROL_REG(TILER_PRESENT_HI):
1711 case GPU_CONTROL_REG(L2_PRESENT_LO):
1712 case GPU_CONTROL_REG(L2_PRESENT_HI):
1713 case GPU_CONTROL_REG(STACK_PRESENT_LO):
1714 case GPU_CONTROL_REG(STACK_PRESENT_HI):
1715 *value = get_implementation_register(addr, dummy->control_reg_values);
1716 break;
1717 case GPU_CONTROL_REG(SHADER_READY_LO):
1718 *value = (dummy->power_on >> 0x02) &
1719 get_implementation_register(GPU_CONTROL_REG(SHADER_PRESENT_LO),
1720 dummy->control_reg_values);
1721 break;
1722 case GPU_CONTROL_REG(TILER_READY_LO):
1723 *value = (dummy->power_on >> 0x01) &
1724 get_implementation_register(GPU_CONTROL_REG(TILER_PRESENT_LO),
1725 dummy->control_reg_values);
1726 break;
1727 case GPU_CONTROL_REG(L2_READY_LO):
1728 *value = dummy->power_on &
1729 get_implementation_register(GPU_CONTROL_REG(L2_PRESENT_LO),
1730 dummy->control_reg_values);
1731 break;
1732 case GPU_CONTROL_REG(STACK_READY_LO):
1733 *value = dummy->stack_power_on_lo &
1734 get_implementation_register(GPU_CONTROL_REG(STACK_PRESENT_LO),
1735 dummy->control_reg_values);
1736 break;
1737
1738 case GPU_CONTROL_REG(SHADER_READY_HI):
1739 case GPU_CONTROL_REG(TILER_READY_HI):
1740 case GPU_CONTROL_REG(L2_READY_HI):
1741 case GPU_CONTROL_REG(STACK_READY_HI):
1742 *value = 0;
1743 break;
1744
1745 case GPU_CONTROL_REG(SHADER_PWRTRANS_LO):
1746 case GPU_CONTROL_REG(SHADER_PWRTRANS_HI):
1747 case GPU_CONTROL_REG(TILER_PWRTRANS_LO):
1748 case GPU_CONTROL_REG(TILER_PWRTRANS_HI):
1749 case GPU_CONTROL_REG(L2_PWRTRANS_LO):
1750 case GPU_CONTROL_REG(L2_PWRTRANS_HI):
1751 case GPU_CONTROL_REG(STACK_PWRTRANS_LO):
1752 case GPU_CONTROL_REG(STACK_PWRTRANS_HI):
1753 *value = 0;
1754 break;
1755
1756 case GPU_CONTROL_REG(SHADER_PWRACTIVE_LO):
1757 case GPU_CONTROL_REG(SHADER_PWRACTIVE_HI):
1758 case GPU_CONTROL_REG(TILER_PWRACTIVE_LO):
1759 case GPU_CONTROL_REG(TILER_PWRACTIVE_HI):
1760 case GPU_CONTROL_REG(L2_PWRACTIVE_LO):
1761 case GPU_CONTROL_REG(L2_PWRACTIVE_HI):
1762 *value = 0;
1763 break;
1764
1765 #if !MALI_USE_CSF
1766 case GPU_CONTROL_REG(JM_CONFIG):
1767 #else /* !MALI_USE_CSF */
1768 case GPU_CONTROL_REG(CSF_CONFIG):
1769 #endif /* !MALI_USE_CSF */
1770
1771 case GPU_CONTROL_REG(SHADER_CONFIG):
1772 case GPU_CONTROL_REG(TILER_CONFIG):
1773 case GPU_CONTROL_REG(L2_MMU_CONFIG):
1774 *value = 0;
1775 break;
1776
1777 case GPU_CONTROL_REG(COHERENCY_FEATURES):
1778 *value = BIT(0) | BIT(1); /* ace_lite and ace, respectively. */
1779 break;
1780 case GPU_CONTROL_REG(COHERENCY_ENABLE):
1781 *value = dummy->coherency_enable;
1782 break;
1783
1784 case GPU_CONTROL_REG(THREAD_TLS_ALLOC):
1785 *value = 0;
1786 break;
1787
1788 default:
1789 model_error_log(KBASE_CORE,
1790 "Dummy model register access: Reading unknown control reg 0x%x\n",
1791 addr);
1792 break;
1793 }
1794 #if !MALI_USE_CSF
1795 } else if ((addr >= JOB_CONTROL_REG(JOB_SLOT0)) &&
1796 (addr < (JOB_CONTROL_REG(JOB_SLOT15) + 0x80))) {
1797 int slot_idx = (addr >> 7) & 0xf;
1798 int sub_reg = addr & 0x7F;
1799
1800 KBASE_DEBUG_ASSERT(slot_idx < NUM_SLOTS);
1801 switch (sub_reg) {
1802 case JS_HEAD_NEXT_LO:
1803 *value = (u32) ((hw_error_status.current_jc) &
1804 0xFFFFFFFF);
1805 break;
1806 case JS_HEAD_NEXT_HI:
1807 *value = (u32) (hw_error_status.current_jc >> 32);
1808 break;
1809 case JS_STATUS:
1810 if (hw_error_status.js_status[slot_idx])
1811 *value = hw_error_status.js_status[slot_idx];
1812 else /* 0x08 means active, 0x00 idle */
1813 *value = (dummy->slots[slot_idx].job_active)
1814 << 3;
1815 break;
1816 case JS_COMMAND_NEXT:
1817 *value = dummy->slots[slot_idx].job_queued;
1818 break;
1819
1820 /* The dummy model does not implement these registers
1821 * avoid printing error messages
1822 */
1823 case JS_HEAD_HI:
1824 case JS_HEAD_LO:
1825 case JS_TAIL_HI:
1826 case JS_TAIL_LO:
1827 case JS_FLUSH_ID_NEXT:
1828 break;
1829
1830 default:
1831 model_error_log(KBASE_CORE,
1832 "Dummy model register access: unknown job slot reg 0x%02X being read\n",
1833 sub_reg);
1834 break;
1835 }
1836 #endif /* !MALI_USE_CSF */
1837 } else if (addr == GPU_CONTROL_REG(AS_PRESENT)) {
1838 *value = dummy->control_reg_values->as_present;
1839 #if !MALI_USE_CSF
1840 } else if (addr == GPU_CONTROL_REG(JS_PRESENT)) {
1841 *value = 0x7;
1842 #endif /* !MALI_USE_CSF */
1843 } else if (addr >= GPU_CONTROL_REG(TEXTURE_FEATURES_0) &&
1844 addr <= GPU_CONTROL_REG(TEXTURE_FEATURES_3)) {
1845 switch (addr) {
1846 case GPU_CONTROL_REG(TEXTURE_FEATURES_0):
1847 *value = 0xfffff;
1848 break;
1849
1850 case GPU_CONTROL_REG(TEXTURE_FEATURES_1):
1851 *value = 0xffff;
1852 break;
1853
1854 case GPU_CONTROL_REG(TEXTURE_FEATURES_2):
1855 *value = 0x9f81ffff;
1856 break;
1857
1858 case GPU_CONTROL_REG(TEXTURE_FEATURES_3):
1859 *value = 0;
1860 break;
1861 }
1862 #if !MALI_USE_CSF
1863 } else if (addr >= GPU_CONTROL_REG(JS0_FEATURES) &&
1864 addr <= GPU_CONTROL_REG(JS15_FEATURES)) {
1865 switch (addr) {
1866 case GPU_CONTROL_REG(JS0_FEATURES):
1867 *value = 0x20e;
1868 break;
1869
1870 case GPU_CONTROL_REG(JS1_FEATURES):
1871 *value = 0x1fe;
1872 break;
1873
1874 case GPU_CONTROL_REG(JS2_FEATURES):
1875 *value = 0x7e;
1876 break;
1877
1878 default:
1879 *value = 0;
1880 break;
1881 }
1882 #endif /* !MALI_USE_CSF */
1883 } else if (addr >= GPU_CONTROL_REG(L2_FEATURES)
1884 && addr <= GPU_CONTROL_REG(MMU_FEATURES)) {
1885 switch (addr) {
1886 case GPU_CONTROL_REG(L2_FEATURES):
1887 *value = 0x6100206;
1888 break;
1889
1890 case GPU_CONTROL_REG(CORE_FEATURES):
1891 *value = dummy->control_reg_values->core_features;
1892 break;
1893
1894 case GPU_CONTROL_REG(TILER_FEATURES):
1895 *value = dummy->control_reg_values->tiler_features;
1896 break;
1897
1898 case GPU_CONTROL_REG(MEM_FEATURES):
1899 /* Bit 0: Core group is coherent */
1900 *value = 0x01;
1901 /* Bits 11:8: L2 slice count - 1 */
1902 *value |= (hweight64(DUMMY_IMPLEMENTATION_L2_PRESENT) - 1) << 8;
1903 break;
1904
1905 case GPU_CONTROL_REG(MMU_FEATURES):
1906 *value = dummy->control_reg_values->mmu_features;
1907 break;
1908 }
1909 } else if (addr >= GPU_CONTROL_REG(THREAD_MAX_THREADS)
1910 && addr <= GPU_CONTROL_REG(THREAD_FEATURES)) {
1911 switch (addr) {
1912 case GPU_CONTROL_REG(THREAD_FEATURES):
1913 *value = dummy->control_reg_values->thread_features
1914 | (IMPLEMENTATION_MODEL << 30);
1915 break;
1916 case GPU_CONTROL_REG(THREAD_MAX_BARRIER_SIZE):
1917 *value = dummy->control_reg_values->thread_max_barrier_size;
1918 break;
1919 case GPU_CONTROL_REG(THREAD_MAX_WORKGROUP_SIZE):
1920 *value = dummy->control_reg_values->thread_max_workgroup_size;
1921 break;
1922 case GPU_CONTROL_REG(THREAD_MAX_THREADS):
1923 *value = dummy->control_reg_values->thread_max_threads;
1924 break;
1925 }
1926 } else if (addr >= GPU_CONTROL_REG(CYCLE_COUNT_LO)
1927 && addr <= GPU_CONTROL_REG(TIMESTAMP_HI)) {
1928 *value = 0;
1929 } else if (addr >= MMU_AS_REG(0, AS_TRANSTAB_LO)
1930 && addr <= MMU_AS_REG(15, AS_STATUS)) {
1931 int mem_addr_space = (addr - MMU_AS_REG(0, AS_TRANSTAB_LO))
1932 >> 6;
1933
1934 switch (addr & 0x3F) {
1935 case AS_TRANSTAB_LO:
1936 *value = (u32)
1937 (hw_error_status.as_transtab[mem_addr_space] &
1938 0xffffffff);
1939 break;
1940
1941 case AS_TRANSTAB_HI:
1942 *value = (u32)
1943 (hw_error_status.as_transtab[mem_addr_space] >>
1944 32);
1945 break;
1946
1947 case AS_STATUS:
1948 *value = 0;
1949 break;
1950
1951 case AS_FAULTSTATUS:
1952 if (mem_addr_space == hw_error_status.faulty_mmu_as)
1953 *value = hw_error_status.as_faultstatus[
1954 hw_error_status.faulty_mmu_as];
1955 else
1956 *value = 0;
1957 break;
1958
1959 case AS_LOCKADDR_LO:
1960 case AS_LOCKADDR_HI:
1961 case AS_MEMATTR_LO:
1962 case AS_MEMATTR_HI:
1963 case AS_TRANSCFG_LO:
1964 case AS_TRANSCFG_HI:
1965 /* Read ignored */
1966 *value = 0;
1967 break;
1968
1969 default:
1970 model_error_log(KBASE_CORE,
1971 "Dummy model register access: Reading unsupported MMU #%d register 0x%x. Returning 0\n",
1972 mem_addr_space, addr);
1973 *value = 0;
1974 break;
1975 }
1976 } else if (addr == MMU_REG(MMU_IRQ_MASK)) {
1977 *value = hw_error_status.mmu_irq_mask;
1978 } else if (addr == MMU_REG(MMU_IRQ_RAWSTAT)) {
1979 *value = hw_error_status.mmu_irq_rawstat;
1980 } else if (addr == MMU_REG(MMU_IRQ_STATUS)) {
1981 *value = hw_error_status.mmu_irq_mask &
1982 hw_error_status.mmu_irq_rawstat;
1983 }
1984 #if MALI_USE_CSF
1985 else if (addr == IPA_CONTROL_REG(STATUS)) {
1986 *value = (ipa_control_timer_enabled << 31);
1987 } else if ((addr >= IPA_CONTROL_REG(VALUE_CSHW_REG_LO(0))) &&
1988 (addr <= IPA_CONTROL_REG(VALUE_CSHW_REG_HI(
1989 IPA_CTL_MAX_VAL_CNT_IDX)))) {
1990 u32 counter_index =
1991 (addr - IPA_CONTROL_REG(VALUE_CSHW_REG_LO(0))) >> 3;
1992 bool is_low_word =
1993 !((addr - IPA_CONTROL_REG(VALUE_CSHW_REG_LO(0))) & 7);
1994
1995 *value = gpu_model_get_prfcnt_value(KBASE_IPA_CORE_TYPE_CSHW,
1996 counter_index, is_low_word);
1997 } else if ((addr >= IPA_CONTROL_REG(VALUE_MEMSYS_REG_LO(0))) &&
1998 (addr <= IPA_CONTROL_REG(VALUE_MEMSYS_REG_HI(
1999 IPA_CTL_MAX_VAL_CNT_IDX)))) {
2000 u32 counter_index =
2001 (addr - IPA_CONTROL_REG(VALUE_MEMSYS_REG_LO(0))) >> 3;
2002 bool is_low_word =
2003 !((addr - IPA_CONTROL_REG(VALUE_MEMSYS_REG_LO(0))) & 7);
2004
2005 *value = gpu_model_get_prfcnt_value(KBASE_IPA_CORE_TYPE_MEMSYS,
2006 counter_index, is_low_word);
2007 } else if ((addr >= IPA_CONTROL_REG(VALUE_TILER_REG_LO(0))) &&
2008 (addr <= IPA_CONTROL_REG(VALUE_TILER_REG_HI(
2009 IPA_CTL_MAX_VAL_CNT_IDX)))) {
2010 u32 counter_index =
2011 (addr - IPA_CONTROL_REG(VALUE_TILER_REG_LO(0))) >> 3;
2012 bool is_low_word =
2013 !((addr - IPA_CONTROL_REG(VALUE_TILER_REG_LO(0))) & 7);
2014
2015 *value = gpu_model_get_prfcnt_value(KBASE_IPA_CORE_TYPE_TILER,
2016 counter_index, is_low_word);
2017 } else if ((addr >= IPA_CONTROL_REG(VALUE_SHADER_REG_LO(0))) &&
2018 (addr <= IPA_CONTROL_REG(VALUE_SHADER_REG_HI(
2019 IPA_CTL_MAX_VAL_CNT_IDX)))) {
2020 u32 counter_index =
2021 (addr - IPA_CONTROL_REG(VALUE_SHADER_REG_LO(0))) >> 3;
2022 bool is_low_word =
2023 !((addr - IPA_CONTROL_REG(VALUE_SHADER_REG_LO(0))) & 7);
2024
2025 *value = gpu_model_get_prfcnt_value(KBASE_IPA_CORE_TYPE_SHADER,
2026 counter_index, is_low_word);
2027 }
2028 #endif
2029 else if (addr == GPU_CONTROL_REG(GPU_FEATURES_LO)) {
2030 *value = dummy->control_reg_values->gpu_features_lo;
2031 } else if (addr == GPU_CONTROL_REG(GPU_FEATURES_HI)) {
2032 *value = dummy->control_reg_values->gpu_features_hi;
2033 } else {
2034 model_error_log(KBASE_CORE,
2035 "Dummy model register access: Reading unsupported register 0x%x. Returning 0\n",
2036 addr);
2037 *value = 0;
2038 }
2039
2040 spin_unlock_irqrestore(&hw_error_status.access_lock, flags);
2041 CSTD_UNUSED(dummy);
2042 }
2043
2044 static u32 set_user_sample_core_type(u64 *counters, u32 *usr_data_start, u32 usr_data_offset,
2045 u32 usr_data_size, u32 core_count)
2046 {
2047 u32 sample_size;
2048 u32 *usr_data = NULL;
2049
2050 lockdep_assert_held(&performance_counters.access_lock);
2051
2052 sample_size =
2053 core_count * KBASE_DUMMY_MODEL_COUNTER_PER_CORE * sizeof(u32);
2054
2055 if ((usr_data_size >= usr_data_offset) &&
2056 (sample_size <= usr_data_size - usr_data_offset))
2057 usr_data = usr_data_start + (usr_data_offset / sizeof(u32));
2058
2059 if (!usr_data)
2060 model_error_log(KBASE_CORE, "Unable to set counter sample 1");
2061 else {
2062 u32 loop_cnt = core_count * KBASE_DUMMY_MODEL_COUNTER_PER_CORE;
2063 u32 i;
2064
2065 for (i = 0; i < loop_cnt; i++) {
2066 counters[i] = usr_data[i];
2067 }
2068 }
2069
2070 return usr_data_offset + sample_size;
2071 }
2072
2073 static u32 set_kernel_sample_core_type(u64 *counters,
2074 u64 *usr_data_start, u32 usr_data_offset,
2075 u32 usr_data_size, u32 core_count)
2076 {
2077 u32 sample_size;
2078 u64 *usr_data = NULL;
2079
2080 lockdep_assert_held(&performance_counters.access_lock);
2081
2082 sample_size =
2083 core_count * KBASE_DUMMY_MODEL_COUNTER_PER_CORE * sizeof(u64);
2084
2085 if ((usr_data_size >= usr_data_offset) &&
2086 (sample_size <= usr_data_size - usr_data_offset))
2087 usr_data = usr_data_start + (usr_data_offset / sizeof(u64));
2088
2089 if (!usr_data)
2090 model_error_log(KBASE_CORE, "Unable to set kernel counter sample 1");
2091 else
2092 memcpy(counters, usr_data, sample_size);
2093
2094 return usr_data_offset + sample_size;
2095 }
2096
2097 /* Counter values injected through ioctl are of 32 bits */
2098 int gpu_model_set_dummy_prfcnt_user_sample(u32 __user *data, u32 size)
2099 {
2100 unsigned long flags;
2101 u32 *user_data;
2102 u32 offset = 0;
2103
2104 if (data == NULL || size == 0 || size > KBASE_DUMMY_MODEL_COUNTER_TOTAL * sizeof(u32))
2105 return -EINVAL;
2106
2107 /* copy_from_user might sleep so can't be called from inside a spinlock
2108 * allocate a temporary buffer for user data and copy to that before taking
2109 * the lock
2110 */
2111 user_data = kmalloc(size, GFP_KERNEL);
2112 if (!user_data)
2113 return -ENOMEM;
2114
2115 if (copy_from_user(user_data, data, size)) {
2116 model_error_log(KBASE_CORE, "Unable to copy prfcnt data from userspace");
2117 kfree(user_data);
2118 return -EINVAL;
2119 }
2120
2121 spin_lock_irqsave(&performance_counters.access_lock, flags);
2122 #if !MALI_USE_CSF
2123 offset = set_user_sample_core_type(performance_counters.jm_counters, user_data, offset,
2124 size, 1);
2125 #else
2126 offset = set_user_sample_core_type(performance_counters.cshw_counters, user_data, offset,
2127 size, 1);
2128 #endif /* !MALI_USE_CSF */
2129 offset = set_user_sample_core_type(performance_counters.tiler_counters, user_data, offset,
2130 size, hweight64(DUMMY_IMPLEMENTATION_TILER_PRESENT));
2131 offset = set_user_sample_core_type(performance_counters.l2_counters, user_data, offset,
2132 size, KBASE_DUMMY_MODEL_MAX_MEMSYS_BLOCKS);
2133 offset = set_user_sample_core_type(performance_counters.shader_counters, user_data, offset,
2134 size, KBASE_DUMMY_MODEL_MAX_SHADER_CORES);
2135 spin_unlock_irqrestore(&performance_counters.access_lock, flags);
2136
2137 kfree(user_data);
2138 return 0;
2139 }
2140
2141 /* Counter values injected through kutf are of 64 bits */
2142 void gpu_model_set_dummy_prfcnt_kernel_sample(u64 *data, u32 size)
2143 {
2144 unsigned long flags;
2145 u32 offset = 0;
2146
2147 spin_lock_irqsave(&performance_counters.access_lock, flags);
2148 #if !MALI_USE_CSF
2149 offset = set_kernel_sample_core_type(performance_counters.jm_counters, data, offset, size,
2150 1);
2151 #else
2152 offset = set_kernel_sample_core_type(performance_counters.cshw_counters, data, offset, size,
2153 1);
2154 #endif /* !MALI_USE_CSF */
2155 offset = set_kernel_sample_core_type(performance_counters.tiler_counters, data, offset,
2156 size, hweight64(DUMMY_IMPLEMENTATION_TILER_PRESENT));
2157 offset = set_kernel_sample_core_type(performance_counters.l2_counters, data, offset, size,
2158 hweight64(performance_counters.l2_present));
2159 offset = set_kernel_sample_core_type(performance_counters.shader_counters, data, offset,
2160 size, hweight64(performance_counters.shader_present));
2161 spin_unlock_irqrestore(&performance_counters.access_lock, flags);
2162 }
2163 KBASE_EXPORT_TEST_API(gpu_model_set_dummy_prfcnt_kernel_sample);
2164
2165 void gpu_model_get_dummy_prfcnt_cores(struct kbase_device *kbdev,
2166 u64 *l2_present, u64 *shader_present)
2167 {
2168 if (shader_present)
2169 *shader_present = performance_counters.shader_present;
2170 if (l2_present)
2171 *l2_present = performance_counters.l2_present;
2172 }
2173 KBASE_EXPORT_TEST_API(gpu_model_get_dummy_prfcnt_cores);
2174
2175 void gpu_model_set_dummy_prfcnt_cores(struct kbase_device *kbdev,
2176 u64 l2_present, u64 shader_present)
2177 {
2178 if (WARN_ON(!l2_present || !shader_present
2179 || hweight64(l2_present) > KBASE_DUMMY_MODEL_MAX_MEMSYS_BLOCKS
2180 || hweight64(shader_present) > KBASE_DUMMY_MODEL_MAX_SHADER_CORES))
2181 return;
2182
2183 performance_counters.l2_present = l2_present;
2184 performance_counters.shader_present = shader_present;
2185
2186 /* Update the GPU properties used by vinstr to calculate the counter
2187 * dump buffer size.
2188 */
2189 kbdev->gpu_props.props.l2_props.num_l2_slices = hweight64(l2_present);
2190 kbdev->gpu_props.props.coherency_info.group[0].core_mask = shader_present;
2191 kbdev->gpu_props.curr_config.l2_slices = hweight64(l2_present);
2192 kbdev->gpu_props.curr_config.shader_present = shader_present;
2193 }
2194 KBASE_EXPORT_TEST_API(gpu_model_set_dummy_prfcnt_cores);
2195
2196 int gpu_model_control(void *model,
2197 struct kbase_model_control_params *params)
2198 {
2199 struct dummy_model_t *dummy = (struct dummy_model_t *)model;
2200 int i;
2201 unsigned long flags;
2202
2203 if (params->command == KBASE_MC_DISABLE_JOBS) {
2204 for (i = 0; i < NUM_SLOTS; i++)
2205 dummy->slots[i].job_disabled = params->value;
2206 } else {
2207 return -EINVAL;
2208 }
2209
2210 spin_lock_irqsave(&hw_error_status.access_lock, flags);
2211 midgard_model_update(dummy);
2212 midgard_model_get_outputs(dummy);
2213 spin_unlock_irqrestore(&hw_error_status.access_lock, flags);
2214
2215 return 0;
2216 }
2217
2218 /**
2219 * kbase_is_gpu_removed - Has the GPU been removed.
2220 * @kbdev: Kbase device pointer
2221 *
2222 * This function would return true if the GPU has been removed.
2223 * It is stubbed here
2224 * Return: Always false
2225 */
2226 bool kbase_is_gpu_removed(struct kbase_device *kbdev)
2227 {
2228 return false;
2229 }
2230