xref: /OK3568_Linux_fs/kernel/drivers/gpu/arm/mali400/mali/common/mali_pp.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (C) 2011-2017 ARM Limited. All rights reserved.
3  *
4  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
6  *
7  * A copy of the licence is included with the program, and can also be obtained from Free Software
8  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
9  */
10 
11 #include "mali_pp_job.h"
12 #include "mali_pp.h"
13 #include "mali_hw_core.h"
14 #include "mali_group.h"
15 #include "regs/mali_200_regs.h"
16 #include "mali_kernel_common.h"
17 #include "mali_kernel_core.h"
18 
19 #if defined(CONFIG_MALI400_PROFILING)
20 #include "mali_osk_profiling.h"
21 #endif
22 
23 /* Number of frame registers on Mali-200 */
24 #define MALI_PP_MALI200_NUM_FRAME_REGISTERS ((0x04C/4)+1)
25 /* Number of frame registers on Mali-300 and later */
26 #define MALI_PP_MALI400_NUM_FRAME_REGISTERS ((0x058/4)+1)
27 
28 static struct mali_pp_core *mali_global_pp_cores[MALI_MAX_NUMBER_OF_PP_CORES] = { NULL };
29 static u32 mali_global_num_pp_cores = 0;
30 
31 /* Interrupt handlers */
32 static void mali_pp_irq_probe_trigger(void *data);
33 static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data);
34 
mali_pp_create(const _mali_osk_resource_t * resource,struct mali_group * group,mali_bool is_virtual,u32 bcast_id)35 struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual, u32 bcast_id)
36 {
37 	struct mali_pp_core *core = NULL;
38 
39 	MALI_DEBUG_PRINT(2, ("Mali PP: Creating Mali PP core: %s\n", resource->description));
40 	MALI_DEBUG_PRINT(2, ("Mali PP: Base address of PP core: 0x%x\n", resource->base));
41 
42 	if (mali_global_num_pp_cores >= MALI_MAX_NUMBER_OF_PP_CORES) {
43 		MALI_PRINT_ERROR(("Mali PP: Too many PP core objects created\n"));
44 		return NULL;
45 	}
46 
47 	core = _mali_osk_calloc(1, sizeof(struct mali_pp_core));
48 	if (NULL != core) {
49 		core->core_id = mali_global_num_pp_cores;
50 		core->bcast_id = bcast_id;
51 
52 		if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI200_REG_SIZEOF_REGISTER_BANK)) {
53 			_mali_osk_errcode_t ret;
54 
55 			if (!is_virtual) {
56 				ret = mali_pp_reset(core);
57 			} else {
58 				ret = _MALI_OSK_ERR_OK;
59 			}
60 
61 			if (_MALI_OSK_ERR_OK == ret) {
62 				ret = mali_group_add_pp_core(group, core);
63 				if (_MALI_OSK_ERR_OK == ret) {
64 					/* Setup IRQ handlers (which will do IRQ probing if needed) */
65 					MALI_DEBUG_ASSERT(!is_virtual || -1 != resource->irq);
66 
67 					core->irq = _mali_osk_irq_init(resource->irq,
68 								       mali_group_upper_half_pp,
69 								       group,
70 								       mali_pp_irq_probe_trigger,
71 								       mali_pp_irq_probe_ack,
72 								       core,
73 								       resource->description);
74 					if (NULL != core->irq) {
75 						mali_global_pp_cores[mali_global_num_pp_cores] = core;
76 						mali_global_num_pp_cores++;
77 
78 						return core;
79 					} else {
80 						MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\n", core->hw_core.description));
81 					}
82 					mali_group_remove_pp_core(group);
83 				} else {
84 					MALI_PRINT_ERROR(("Mali PP: Failed to add core %s to group\n", core->hw_core.description));
85 				}
86 			}
87 			mali_hw_core_delete(&core->hw_core);
88 		}
89 
90 		_mali_osk_free(core);
91 	} else {
92 		MALI_PRINT_ERROR(("Mali PP: Failed to allocate memory for PP core\n"));
93 	}
94 
95 	return NULL;
96 }
97 
mali_pp_delete(struct mali_pp_core * core)98 void mali_pp_delete(struct mali_pp_core *core)
99 {
100 	u32 i;
101 
102 	MALI_DEBUG_ASSERT_POINTER(core);
103 
104 	_mali_osk_irq_term(core->irq);
105 	mali_hw_core_delete(&core->hw_core);
106 
107 	/* Remove core from global list */
108 	for (i = 0; i < mali_global_num_pp_cores; i++) {
109 		if (mali_global_pp_cores[i] == core) {
110 			mali_global_pp_cores[i] = NULL;
111 			mali_global_num_pp_cores--;
112 
113 			if (i != mali_global_num_pp_cores) {
114 				/* We removed a PP core from the middle of the array -- move the last
115 				 * PP core to the current position to close the gap */
116 				mali_global_pp_cores[i] = mali_global_pp_cores[mali_global_num_pp_cores];
117 				mali_global_pp_cores[mali_global_num_pp_cores] = NULL;
118 			}
119 
120 			break;
121 		}
122 	}
123 
124 	_mali_osk_free(core);
125 }
126 
mali_pp_stop_bus(struct mali_pp_core * core)127 void mali_pp_stop_bus(struct mali_pp_core *core)
128 {
129 	MALI_DEBUG_ASSERT_POINTER(core);
130 	/* Will only send the stop bus command, and not wait for it to complete */
131 	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
132 }
133 
mali_pp_stop_bus_wait(struct mali_pp_core * core)134 _mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core)
135 {
136 	int i;
137 
138 	MALI_DEBUG_ASSERT_POINTER(core);
139 
140 	/* Send the stop bus command. */
141 	mali_pp_stop_bus(core);
142 
143 	/* Wait for bus to be stopped */
144 	for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) {
145 		if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED)
146 			break;
147 	}
148 
149 	if (MALI_REG_POLL_COUNT_FAST == i) {
150 		MALI_PRINT_ERROR(("Mali PP: Failed to stop bus on %s. Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
151 		return _MALI_OSK_ERR_FAULT;
152 	}
153 	return _MALI_OSK_ERR_OK;
154 }
155 
156 /* Frame register reset values.
157  * Taken from the Mali400 TRM, 3.6. Pixel processor control register summary */
158 static const u32 mali_frame_registers_reset_values[_MALI_PP_MAX_FRAME_REGISTERS] = {
159 	0x0, /* Renderer List Address Register */
160 	0x0, /* Renderer State Word Base Address Register */
161 	0x0, /* Renderer Vertex Base Register */
162 	0x2, /* Feature Enable Register */
163 	0x0, /* Z Clear Value Register */
164 	0x0, /* Stencil Clear Value Register */
165 	0x0, /* ABGR Clear Value 0 Register */
166 	0x0, /* ABGR Clear Value 1 Register */
167 	0x0, /* ABGR Clear Value 2 Register */
168 	0x0, /* ABGR Clear Value 3 Register */
169 	0x0, /* Bounding Box Left Right Register */
170 	0x0, /* Bounding Box Bottom Register */
171 	0x0, /* FS Stack Address Register */
172 	0x0, /* FS Stack Size and Initial Value Register */
173 	0x0, /* Reserved */
174 	0x0, /* Reserved */
175 	0x0, /* Origin Offset X Register */
176 	0x0, /* Origin Offset Y Register */
177 	0x75, /* Subpixel Specifier Register */
178 	0x0, /* Tiebreak mode Register */
179 	0x0, /* Polygon List Format Register */
180 	0x0, /* Scaling Register */
181 	0x0 /* Tilebuffer configuration Register */
182 };
183 
184 /* WBx register reset values */
185 static const u32 mali_wb_registers_reset_values[_MALI_PP_MAX_WB_REGISTERS] = {
186 	0x0, /* WBx Source Select Register */
187 	0x0, /* WBx Target Address Register */
188 	0x0, /* WBx Target Pixel Format Register */
189 	0x0, /* WBx Target AA Format Register */
190 	0x0, /* WBx Target Layout */
191 	0x0, /* WBx Target Scanline Length */
192 	0x0, /* WBx Target Flags Register */
193 	0x0, /* WBx MRT Enable Register */
194 	0x0, /* WBx MRT Offset Register */
195 	0x0, /* WBx Global Test Enable Register */
196 	0x0, /* WBx Global Test Reference Value Register */
197 	0x0  /* WBx Global Test Compare Function Register */
198 };
199 
200 /* Performance Counter 0 Enable Register reset value */
201 static const u32 mali_perf_cnt_enable_reset_value = 0;
202 
mali_pp_hard_reset(struct mali_pp_core * core)203 _mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core)
204 {
205 	/* Bus must be stopped before calling this function */
206 	const u32 reset_wait_target_register = MALI200_REG_ADDR_MGMT_PERF_CNT_0_LIMIT;
207 	const u32 reset_invalid_value = 0xC0FFE000;
208 	const u32 reset_check_value = 0xC01A0000;
209 	int i;
210 
211 	MALI_DEBUG_ASSERT_POINTER(core);
212 	MALI_DEBUG_PRINT(2, ("Mali PP: Hard reset of core %s\n", core->hw_core.description));
213 
214 	/* Set register to a bogus value. The register will be used to detect when reset is complete */
215 	mali_hw_core_register_write_relaxed(&core->hw_core, reset_wait_target_register, reset_invalid_value);
216 	mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
217 
218 	/* Force core to reset */
219 	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET);
220 
221 	/* Wait for reset to be complete */
222 	for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) {
223 		mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_check_value);
224 		if (reset_check_value == mali_hw_core_register_read(&core->hw_core, reset_wait_target_register)) {
225 			break;
226 		}
227 	}
228 
229 	if (MALI_REG_POLL_COUNT_FAST == i) {
230 		MALI_PRINT_ERROR(("Mali PP: The hard reset loop didn't work, unable to recover\n"));
231 	}
232 
233 	mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, 0x00000000); /* set it back to the default */
234 	/* Re-enable interrupts */
235 	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
236 	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
237 
238 	return _MALI_OSK_ERR_OK;
239 }
240 
mali_pp_reset_async(struct mali_pp_core * core)241 void mali_pp_reset_async(struct mali_pp_core *core)
242 {
243 	MALI_DEBUG_ASSERT_POINTER(core);
244 
245 	MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description));
246 
247 	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
248 	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_MASK_ALL);
249 	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET);
250 }
251 
mali_pp_reset_wait(struct mali_pp_core * core)252 _mali_osk_errcode_t mali_pp_reset_wait(struct mali_pp_core *core)
253 {
254 	int i;
255 	u32 rawstat = 0;
256 
257 	for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) {
258 		u32 status =  mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS);
259 		if (!(status & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE)) {
260 			rawstat = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT);
261 			if (rawstat == MALI400PP_REG_VAL_IRQ_RESET_COMPLETED) {
262 				break;
263 			}
264 		}
265 	}
266 
267 	if (i == MALI_REG_POLL_COUNT_FAST) {
268 		MALI_PRINT_ERROR(("Mali PP: Failed to reset core %s, rawstat: 0x%08x\n",
269 				  core->hw_core.description, rawstat));
270 		return _MALI_OSK_ERR_FAULT;
271 	}
272 
273 	/* Re-enable interrupts */
274 	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
275 	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
276 
277 	return _MALI_OSK_ERR_OK;
278 }
279 
mali_pp_reset(struct mali_pp_core * core)280 _mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core)
281 {
282 	mali_pp_reset_async(core);
283 	return mali_pp_reset_wait(core);
284 }
285 
mali_pp_job_start(struct mali_pp_core * core,struct mali_pp_job * job,u32 sub_job,mali_bool restart_virtual)286 void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job, mali_bool restart_virtual)
287 {
288 	u32 relative_address;
289 	u32 start_index;
290 	u32 nr_of_regs;
291 	u32 *frame_registers = mali_pp_job_get_frame_registers(job);
292 	u32 *wb0_registers = mali_pp_job_get_wb0_registers(job);
293 	u32 *wb1_registers = mali_pp_job_get_wb1_registers(job);
294 	u32 *wb2_registers = mali_pp_job_get_wb2_registers(job);
295 	u32 counter_src0 = mali_pp_job_get_perf_counter_src0(job, sub_job);
296 	u32 counter_src1 = mali_pp_job_get_perf_counter_src1(job, sub_job);
297 
298 	MALI_DEBUG_ASSERT_POINTER(core);
299 
300 	/* Write frame registers */
301 
302 	/*
303 	 * There are two frame registers which are different for each sub job:
304 	 * 1. The Renderer List Address Register (MALI200_REG_ADDR_FRAME)
305 	 * 2. The FS Stack Address Register (MALI200_REG_ADDR_STACK)
306 	 */
307 	mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_FRAME / sizeof(u32)]);
308 
309 	/* For virtual jobs, the stack address shouldn't be broadcast but written individually */
310 	if (!mali_pp_job_is_virtual(job) || restart_virtual) {
311 		mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_STACK / sizeof(u32)]);
312 	}
313 
314 	/* Write registers between MALI200_REG_ADDR_FRAME and MALI200_REG_ADDR_STACK */
315 	relative_address = MALI200_REG_ADDR_RSW;
316 	start_index = MALI200_REG_ADDR_RSW / sizeof(u32);
317 	nr_of_regs = (MALI200_REG_ADDR_STACK - MALI200_REG_ADDR_RSW) / sizeof(u32);
318 
319 	mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
320 			relative_address, &frame_registers[start_index],
321 			nr_of_regs, &mali_frame_registers_reset_values[start_index]);
322 
323 	/* MALI200_REG_ADDR_STACK_SIZE */
324 	relative_address = MALI200_REG_ADDR_STACK_SIZE;
325 	start_index = MALI200_REG_ADDR_STACK_SIZE / sizeof(u32);
326 
327 	mali_hw_core_register_write_relaxed_conditional(&core->hw_core,
328 			relative_address, frame_registers[start_index],
329 			mali_frame_registers_reset_values[start_index]);
330 
331 	/* Skip 2 reserved registers */
332 
333 	/* Write remaining registers */
334 	relative_address = MALI200_REG_ADDR_ORIGIN_OFFSET_X;
335 	start_index = MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
336 	nr_of_regs = MALI_PP_MALI400_NUM_FRAME_REGISTERS - MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
337 
338 	mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
339 			relative_address, &frame_registers[start_index],
340 			nr_of_regs, &mali_frame_registers_reset_values[start_index]);
341 
342 	/* Write WBx registers */
343 	if (wb0_registers[0]) { /* M200_WB0_REG_SOURCE_SELECT register */
344 		mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
345 	}
346 
347 	if (wb1_registers[0]) { /* M200_WB1_REG_SOURCE_SELECT register */
348 		mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
349 	}
350 
351 	if (wb2_registers[0]) { /* M200_WB2_REG_SOURCE_SELECT register */
352 		mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
353 	}
354 
355 	if (MALI_HW_CORE_NO_COUNTER != counter_src0) {
356 		mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, counter_src0);
357 		mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
358 	}
359 	if (MALI_HW_CORE_NO_COUNTER != counter_src1) {
360 		mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, counter_src1);
361 		mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
362 	}
363 
364 #ifdef CONFIG_MALI400_HEATMAPS_ENABLED
365 	if (job->uargs.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_HEATMAP_ENABLE) {
366 		mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERFMON_CONTR, ((job->uargs.tilesx & 0x3FF) << 16) | 1);
367 		mali_hw_core_register_write_relaxed(&core->hw_core,  MALI200_REG_ADDR_MGMT_PERFMON_BASE, job->uargs.heatmap_mem & 0xFFFFFFF8);
368 	}
369 #endif /* CONFIG_MALI400_HEATMAPS_ENABLED */
370 
371 	MALI_DEBUG_PRINT(3, ("Mali PP: Starting job 0x%08X part %u/%u on PP core %s\n", job, sub_job + 1, mali_pp_job_get_sub_job_count(job), core->hw_core.description));
372 
373 	/* Adding barrier to make sure all rester writes are finished */
374 	_mali_osk_write_mem_barrier();
375 
376 	/* This is the command that starts the core.
377 	 *
378 	 * Don't actually run the job if PROFILING_SKIP_PP_JOBS are set, just
379 	 * force core to assert the completion interrupt.
380 	 */
381 #if !defined(PROFILING_SKIP_PP_JOBS)
382 	mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);
383 #else
384 	mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_END_OF_FRAME);
385 #endif
386 
387 	/* Adding barrier to make sure previous rester writes is finished */
388 	_mali_osk_write_mem_barrier();
389 }
390 
mali_pp_core_get_version(struct mali_pp_core * core)391 u32 mali_pp_core_get_version(struct mali_pp_core *core)
392 {
393 	MALI_DEBUG_ASSERT_POINTER(core);
394 	return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION);
395 }
396 
mali_pp_get_global_pp_core(u32 index)397 struct mali_pp_core *mali_pp_get_global_pp_core(u32 index)
398 {
399 	if (mali_global_num_pp_cores > index) {
400 		return mali_global_pp_cores[index];
401 	}
402 
403 	return NULL;
404 }
405 
mali_pp_get_glob_num_pp_cores(void)406 u32 mali_pp_get_glob_num_pp_cores(void)
407 {
408 	return mali_global_num_pp_cores;
409 }
410 
411 /* ------------- interrupt handling below ------------------ */
mali_pp_irq_probe_trigger(void * data)412 static void mali_pp_irq_probe_trigger(void *data)
413 {
414 	struct mali_pp_core *core = (struct mali_pp_core *)data;
415 	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
416 	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_BUS_ERROR);
417 	_mali_osk_mem_barrier();
418 }
419 
mali_pp_irq_probe_ack(void * data)420 static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data)
421 {
422 	struct mali_pp_core *core = (struct mali_pp_core *)data;
423 	u32 irq_readout;
424 
425 	irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS);
426 	if (MALI200_REG_VAL_IRQ_BUS_ERROR & irq_readout) {
427 		mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_BUS_ERROR);
428 		_mali_osk_mem_barrier();
429 		return _MALI_OSK_ERR_OK;
430 	}
431 
432 	return _MALI_OSK_ERR_FAULT;
433 }
434 
435 
436 #if 0
437 static void mali_pp_print_registers(struct mali_pp_core *core)
438 {
439 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_VERSION = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION)));
440 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR)));
441 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
442 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT)));
443 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_MASK = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK)));
444 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS)));
445 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS)));
446 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE)));
447 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC)));
448 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE)));
449 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE)));
450 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC)));
451 	MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE)));
452 }
453 #endif
454 
455 #if 0
456 void mali_pp_print_state(struct mali_pp_core *core)
457 {
458 	MALI_DEBUG_PRINT(2, ("Mali PP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
459 }
460 #endif
461 
mali_pp_update_performance_counters(struct mali_pp_core * parent,struct mali_pp_core * child,struct mali_pp_job * job,u32 subjob)462 void mali_pp_update_performance_counters(struct mali_pp_core *parent, struct mali_pp_core *child, struct mali_pp_job *job, u32 subjob)
463 {
464 	u32 val0 = 0;
465 	u32 val1 = 0;
466 	u32 counter_src0 = mali_pp_job_get_perf_counter_src0(job, subjob);
467 	u32 counter_src1 = mali_pp_job_get_perf_counter_src1(job, subjob);
468 #if defined(CONFIG_MALI400_PROFILING)
469 	int counter_index = COUNTER_FP_0_C0 + (2 * child->core_id);
470 #endif
471 
472 	if (MALI_HW_CORE_NO_COUNTER != counter_src0) {
473 		val0 = mali_hw_core_register_read(&child->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
474 		mali_pp_job_set_perf_counter_value0(job, subjob, val0);
475 
476 #if defined(CONFIG_MALI400_PROFILING)
477 		_mali_osk_profiling_report_hw_counter(counter_index, val0);
478 		_mali_osk_profiling_record_global_counters(counter_index, val0);
479 #endif
480 	}
481 
482 	if (MALI_HW_CORE_NO_COUNTER != counter_src1) {
483 		val1 = mali_hw_core_register_read(&child->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
484 		mali_pp_job_set_perf_counter_value1(job, subjob, val1);
485 
486 #if defined(CONFIG_MALI400_PROFILING)
487 		_mali_osk_profiling_report_hw_counter(counter_index + 1, val1);
488 		_mali_osk_profiling_record_global_counters(counter_index + 1, val1);
489 #endif
490 	}
491 }
492 
493 #if MALI_STATE_TRACKING
mali_pp_dump_state(struct mali_pp_core * core,char * buf,u32 size)494 u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size)
495 {
496 	int n = 0;
497 
498 	n += _mali_osk_snprintf(buf + n, size - n, "\tPP #%d: %s\n", core->core_id, core->hw_core.description);
499 
500 	return n;
501 }
502 #endif
503