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