aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/arm/utgard/common/mali_group.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/arm/utgard/common/mali_group.c')
-rw-r--r--drivers/gpu/arm/utgard/common/mali_group.c177
1 files changed, 170 insertions, 7 deletions
diff --git a/drivers/gpu/arm/utgard/common/mali_group.c b/drivers/gpu/arm/utgard/common/mali_group.c
index 09f65543d071..b4cd3a1fcd8c 100644
--- a/drivers/gpu/arm/utgard/common/mali_group.c
+++ b/drivers/gpu/arm/utgard/common/mali_group.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
- *
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ *
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
+ *
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@@ -44,6 +44,7 @@ static void mali_group_bottom_half_mmu(void *data);
static void mali_group_bottom_half_gp(void *data);
static void mali_group_bottom_half_pp(void *data);
static void mali_group_timeout(void *data);
+static void mali_group_out_of_memory(void *data);
static void mali_group_reset_pp(struct mali_group *group);
static void mali_group_reset_mmu(struct mali_group *group);
@@ -195,6 +196,11 @@ _mali_osk_errcode_t mali_group_add_gp_core(struct mali_group *group, struct mali
if (NULL == group->bottom_half_work_gp) {
return _MALI_OSK_ERR_FAULT;
}
+
+ group->oom_work_handler = _mali_osk_wq_create_work(mali_group_out_of_memory, group);
+ if (NULL == group->oom_work_handler) {
+ _mali_osk_wq_delete_work(group->bottom_half_work_gp);
+ }
return _MALI_OSK_ERR_OK;
}
@@ -205,6 +211,10 @@ void mali_group_remove_gp_core(struct mali_group *group)
if (NULL != group->bottom_half_work_gp) {
_mali_osk_wq_delete_work(group->bottom_half_work_gp);
}
+
+ if (NULL != group->oom_work_handler) {
+ _mali_osk_wq_delete_work(group->oom_work_handler);
+ }
}
_mali_osk_errcode_t mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core *pp_core)
@@ -460,7 +470,7 @@ void mali_group_power_up(struct mali_group *group)
group->power_is_on = MALI_TRUE;
if (MALI_FALSE == mali_group_is_virtual(group)
- && MALI_FALSE == mali_group_is_in_virtual(group)) {
+ && MALI_FALSE == mali_group_is_in_virtual(group)) {
mali_group_reset(group);
}
@@ -520,6 +530,71 @@ MALI_DEBUG_CODE(static void mali_group_print_virtual(struct mali_group *vgroup)
}
})
+static void mali_group_dump_core_status(struct mali_group *group)
+{
+ u32 i;
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT(NULL != group->gp_core || (NULL != group->pp_core && !mali_group_is_virtual(group)));
+
+ if (NULL != group->gp_core) {
+ MALI_PRINT(("Dump Group %s\n", group->gp_core->hw_core.description));
+
+ for (i = 0; i < 0xA8; i += 0x10) {
+ MALI_PRINT(("0x%04x: 0x%08x 0x%08x 0x%08x 0x%08x\n", i, mali_hw_core_register_read(&group->gp_core->hw_core, i),
+ mali_hw_core_register_read(&group->gp_core->hw_core, i + 4),
+ mali_hw_core_register_read(&group->gp_core->hw_core, i + 8),
+ mali_hw_core_register_read(&group->gp_core->hw_core, i + 12)));
+ }
+
+
+ } else {
+ MALI_PRINT(("Dump Group %s\n", group->pp_core->hw_core.description));
+
+ for (i = 0; i < 0x5c; i += 0x10) {
+ MALI_PRINT(("0x%04x: 0x%08x 0x%08x 0x%08x 0x%08x\n", i, mali_hw_core_register_read(&group->pp_core->hw_core, i),
+ mali_hw_core_register_read(&group->pp_core->hw_core, i + 4),
+ mali_hw_core_register_read(&group->pp_core->hw_core, i + 8),
+ mali_hw_core_register_read(&group->pp_core->hw_core, i + 12)));
+ }
+
+ /* Ignore some minor registers */
+ for (i = 0x1000; i < 0x1068; i += 0x10) {
+ MALI_PRINT(("0x%04x: 0x%08x 0x%08x 0x%08x 0x%08x\n", i, mali_hw_core_register_read(&group->pp_core->hw_core, i),
+ mali_hw_core_register_read(&group->pp_core->hw_core, i + 4),
+ mali_hw_core_register_read(&group->pp_core->hw_core, i + 8),
+ mali_hw_core_register_read(&group->pp_core->hw_core, i + 12)));
+ }
+ }
+
+ MALI_PRINT(("Dump Group MMU\n"));
+ for (i = 0; i < 0x24; i += 0x10) {
+ MALI_PRINT(("0x%04x: 0x%08x 0x%08x 0x%08x 0x%08x\n", i, mali_hw_core_register_read(&group->mmu->hw_core, i),
+ mali_hw_core_register_read(&group->mmu->hw_core, i + 4),
+ mali_hw_core_register_read(&group->mmu->hw_core, i + 8),
+ mali_hw_core_register_read(&group->mmu->hw_core, i + 12)));
+ }
+}
+
+
+/**
+ * @Dump group status
+ */
+void mali_group_dump_status(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ if (mali_group_is_virtual(group)) {
+ struct mali_group *group_c;
+ struct mali_group *temp;
+ _MALI_OSK_LIST_FOREACHENTRY(group_c, temp, &group->group_list, struct mali_group, group_list) {
+ mali_group_dump_core_status(group_c);
+ }
+ } else {
+ mali_group_dump_core_status(group);
+ }
+}
+
/**
* @brief Add child group to virtual group parent
*/
@@ -1353,6 +1428,15 @@ _mali_osk_errcode_t mali_group_upper_half_mmu(void *data)
MALI_DEBUG_ASSERT_POINTER(group);
MALI_DEBUG_ASSERT_POINTER(group->mmu);
+#if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_lock();
+ if (!mali_group_is_working(group)) {
+ /* Not working, so nothing to do */
+ mali_executor_unlock();
+ return _MALI_OSK_ERR_FAULT;
+ }
+#endif
if (NULL != group->gp_core) {
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
@@ -1370,9 +1454,23 @@ _mali_osk_errcode_t mali_group_upper_half_mmu(void *data)
mali_pp_core_get_id(group->pp_core)),
mali_mmu_get_rawstat(group->mmu), 0);
}
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_unlock();
+#endif
+#endif
ret = mali_executor_interrupt_mmu(group, MALI_TRUE);
+#if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_lock();
+ if (!mali_group_is_working(group)) {
+ /* Not working, so nothing to do */
+ mali_executor_unlock();
+ return _MALI_OSK_ERR_FAULT;
+ }
+#endif
+
if (NULL != group->gp_core) {
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
@@ -1389,6 +1487,10 @@ _mali_osk_errcode_t mali_group_upper_half_mmu(void *data)
mali_pp_core_get_id(group->pp_core)),
mali_mmu_get_rawstat(group->mmu), 0);
}
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_unlock();
+#endif
+#endif
return ret;
}
@@ -1447,6 +1549,15 @@ _mali_osk_errcode_t mali_group_upper_half_gp(void *data)
MALI_DEBUG_ASSERT_POINTER(group->gp_core);
MALI_DEBUG_ASSERT_POINTER(group->mmu);
+#if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_lock();
+ if (!mali_group_is_working(group)) {
+ /* Not working, so nothing to do */
+ mali_executor_unlock();
+ return _MALI_OSK_ERR_FAULT;
+ }
+#endif
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
@@ -1457,16 +1568,31 @@ _mali_osk_errcode_t mali_group_upper_half_gp(void *data)
MALI_DEBUG_PRINT(4, ("Group: Interrupt 0x%08X from %s\n",
mali_gp_get_rawstat(group->gp_core),
mali_group_core_description(group)));
-
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_unlock();
+#endif
+#endif
ret = mali_executor_interrupt_gp(group, MALI_TRUE);
+#if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_lock();
+ if (!mali_group_is_working(group)) {
+ /* Not working, so nothing to do */
+ mali_executor_unlock();
+ return _MALI_OSK_ERR_FAULT;
+ }
+#endif
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
0, 0, /* No pid and tid for interrupt handler */
MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0),
mali_gp_get_rawstat(group->gp_core), 0);
-
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_unlock();
+#endif
+#endif
return ret;
}
@@ -1504,6 +1630,16 @@ _mali_osk_errcode_t mali_group_upper_half_pp(void *data)
MALI_DEBUG_ASSERT_POINTER(group->pp_core);
MALI_DEBUG_ASSERT_POINTER(group->mmu);
+#if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_lock();
+ if (!mali_group_is_working(group)) {
+ /* Not working, so nothing to do */
+ mali_executor_unlock();
+ return _MALI_OSK_ERR_FAULT;
+ }
+#endif
+
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
@@ -1515,9 +1651,22 @@ _mali_osk_errcode_t mali_group_upper_half_pp(void *data)
MALI_DEBUG_PRINT(4, ("Group: Interrupt 0x%08X from %s\n",
mali_pp_get_rawstat(group->pp_core),
mali_group_core_description(group)));
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_unlock();
+#endif
+#endif
ret = mali_executor_interrupt_pp(group, MALI_TRUE);
+#if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_lock();
+ if (!mali_group_is_working(group)) {
+ /* Not working, so nothing to do */
+ mali_executor_unlock();
+ return _MALI_OSK_ERR_FAULT;
+ }
+#endif
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
@@ -1525,7 +1674,10 @@ _mali_osk_errcode_t mali_group_upper_half_pp(void *data)
MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(
mali_pp_core_get_id(group->pp_core)),
mali_pp_get_rawstat(group->pp_core), 0);
-
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_executor_unlock();
+#endif
+#endif
return ret;
}
@@ -1573,6 +1725,17 @@ static void mali_group_timeout(void *data)
}
}
+static void mali_group_out_of_memory(void *data)
+{
+ struct mali_group *group = (struct mali_group *)data;
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT_POINTER(group->gp_core);
+ MALI_DEBUG_ASSERT_POINTER(group->mmu);
+
+ mali_executor_group_oom(group);
+}
+
mali_bool mali_group_zap_session(struct mali_group *group,
struct mali_session_data *session)
{