diff options
Diffstat (limited to 'drivers/gpu/arm/utgard/common/mali_group.c')
-rw-r--r-- | drivers/gpu/arm/utgard/common/mali_group.c | 177 |
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) { |