/* ------------- interrupt handling below ------------------ */ static _mali_osk_errcode_t mali_pp_upper_half(void *data) { struct mali_pp_core *core = (struct mali_pp_core *)data; u32 irq_readout; #if !defined(MSTAR_RIU_ENABLED) || (MSTAR_RIU_ADDRESS_TYPE == 32) irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS); #else irq_readout = mali_hw_core_register_read_no_lock(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS); #endif if (MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout) { /* Mask out all IRQs from this core until IRQ is handled */ #if !defined(MSTAR_RIU_ENABLED) || (MSTAR_RIU_ADDRESS_TYPE == 32) mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE); #else mali_hw_core_register_write_no_lock(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE); #endif #if MALI_TIMELINE_PROFILING_ENABLED _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); #endif /* We do need to handle this in a bottom half */ _mali_osk_irq_schedulework(core->irq); return _MALI_OSK_ERR_OK; } return _MALI_OSK_ERR_FAULT; }
static _mali_osk_errcode_t mali_mmu_upper_half(void * data) { struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; u32 int_stat; MALI_DEBUG_ASSERT_POINTER(mmu); /* Check if it was our device which caused the interrupt (we could be sharing the IRQ line) */ int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS); if (0 != int_stat) { mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, 0); mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT) { _mali_osk_irq_schedulework(mmu->irq); } if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR) { /* clear interrupt flag */ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR); /* reenable it */ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK) | MALI_MMU_INTERRUPT_READ_BUS_ERROR); MALI_PRINT_ERROR(("Mali MMU: Read bus error\n")); } return _MALI_OSK_ERR_OK; } return _MALI_OSK_ERR_FAULT; }
static _mali_osk_errcode_t mali_gp_upper_half(void *data) { struct mali_gp_core *core = (struct mali_gp_core *)data; u32 irq_readout = 0; #if MALI_SHARED_INTERRUPTS mali_pm_lock(); if (MALI_TRUE == mali_pm_is_powered_on()) { #endif irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT); #if MALI_SHARED_INTERRUPTS } mali_pm_unlock(); #endif if (MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout) { mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE); #if MALI_TIMELINE_PROFILING_ENABLED _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); #endif _mali_osk_irq_schedulework(core->irq); return _MALI_OSK_ERR_OK; } return _MALI_OSK_ERR_FAULT; }
/** * Symbian OS Power Up call to the driver */ void power_test_callback( void *arg ) { _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; MALI_DEBUG_ASSERT_POINTER(pmm); power_test_flag = MALI_TRUE; _mali_osk_irq_schedulework( pmm->irq ); }
/* callback function for pp core timeout */ static void mali_pp_timeout(void *data) { struct mali_pp_core * core = ((struct mali_pp_core *)data); MALI_DEBUG_PRINT(3, ("Mali PP: TIMEOUT callback \n")); core->core_timed_out = MALI_TRUE; _mali_osk_irq_schedulework(core->irq); }
void malipmm_set_policy_check() { _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; MALI_DEBUG_ASSERT_POINTER(pmm); pmm->check_policy = MALI_TRUE; /* To check the policy we need to schedule some work */ _mali_osk_irq_schedulework( pmm->irq ); }
void _mali_ukk_pmm_event_message( _mali_uk_pmm_message_s *args ) { _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; _mali_osk_notification_t *msg; mali_pmm_message_t *event; MALI_DEBUG_ASSERT_POINTER(pmm); MALI_DEBUG_ASSERT_POINTER(args); MALIPMM_DEBUG_PRINT( ("PMM: sending message\n") ); #if MALI_PMM_TRACE && MALI_PMM_TRACE_SENT_EVENTS _mali_pmm_trace_event_message( args, MALI_FALSE ); #endif msg = _mali_osk_notification_create( MALI_PMM_NOTIFICATION_TYPE, sizeof( mali_pmm_message_t ) ); if( msg ) { event = (mali_pmm_message_t *)msg->result_buffer; event->id = args->id; event->ts = _mali_osk_time_tickcount(); event->data = args->data; _mali_osk_atomic_inc( &(pmm->messages_queued) ); if( args->id > MALI_PMM_EVENT_INTERNALS ) { /* Internal PMM message */ _mali_osk_notification_queue_send( pmm->iqueue, msg ); #if MALI_PMM_TRACE pmm->imessages_sent++; #endif } else { /* Real event */ _mali_osk_notification_queue_send( pmm->queue, msg ); #if MALI_PMM_TRACE pmm->messages_sent++; #endif } } else { MALI_PRINT_ERROR( ("PMM: Could not send message %d", args->id) ); /* Make note of this OOM - which has caused a missed event */ pmm->missed++; } /* Schedule time to look at the event or the fact we couldn't create an event */ _mali_osk_irq_schedulework( pmm->irq ); }
/* ------------- interrupt handling below ------------------ */ static _mali_osk_errcode_t mali_gp_upper_half(void *data) { struct mali_gp_core *core = (struct mali_gp_core *)data; u32 irq_readout; irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT); if (MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout) { /* Mask out all IRQs from this core until IRQ is handled */ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE); #if MALI_TIMELINE_PROFILING_ENABLED _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); #endif /* We do need to handle this in a bottom half */ _mali_osk_irq_schedulework(core->irq); return _MALI_OSK_ERR_OK; } return _MALI_OSK_ERR_FAULT; }
/* ------------- interrupt handling below ------------------ */ static _mali_osk_errcode_t mali_mmu_upper_half(void * data) { struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; u32 int_stat; MALI_DEBUG_ASSERT_POINTER(mmu); /* Check if it was our device which caused the interrupt (we could be sharing the IRQ line) */ //MALI_DEBUG_PRINT(5, ("Mali MMU: %d..\n",mmu->id)); #ifdef CONFIG_ARCH_MESON6 if ( MALI_FALSE == mali_group_power_is_on_2(mmu->group) ) { if (mmu->id == 2) malifix_set_mmu_int_process_state(0, MMU_INT_NONE); else if (mmu->id == 3) malifix_set_mmu_int_process_state(1, MMU_INT_NONE); MALI_DEBUG_PRINT(4, ("Mali MMU: invalid interrupt. <<-- \n")); MALI_SUCCESS; } #endif int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS); if (0 != int_stat) { mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, 0); mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT) { #ifdef CONFIG_ARCH_MESON6 MALI_DEBUG_PRINT(3, ("Mali MMU: core0 page fault reply. <<-- \n")); if (mmu->id == 2) malifix_set_mmu_int_process_state(0, MMU_INT_TOP); else if (mmu->id == 3) malifix_set_mmu_int_process_state(1, MMU_INT_TOP); #endif _mali_osk_irq_schedulework(mmu->irq); } if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR) { /* clear interrupt flag */ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR); /* reenable it */ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK) | MALI_MMU_INTERRUPT_READ_BUS_ERROR); MALI_PRINT_ERROR(("Mali MMU: Read bus error\n")); #ifdef CONFIG_ARCH_MESON6 if (mmu->id == 2) { if (malifix_get_mmu_int_process_state(0) == MMU_INT_TOP) malifix_set_mmu_int_process_state(0, MMU_INT_NONE); } else if (mmu->id == 3) { if (malifix_get_mmu_int_process_state(1) == MMU_INT_TOP) malifix_set_mmu_int_process_state(1, MMU_INT_NONE); } #endif } return _MALI_OSK_ERR_OK; } #ifdef CONFIG_ARCH_MESON6 else { if (mmu->id == 2) malifix_set_mmu_int_process_state(0, MMU_INT_NONE); else if (mmu->id == 3) malifix_set_mmu_int_process_state(1, MMU_INT_NONE); } #endif return _MALI_OSK_ERR_FAULT; }
static void pmm_event_process( void ) { _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; _mali_osk_notification_t *msg = NULL; _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; mali_pmm_message_t *event; u32 process_messages; MALI_DEBUG_ASSERT_POINTER(pmm); /* Max number of messages to process before exiting - as we shouldn't stay * processing the messages for a long time */ process_messages = _mali_osk_atomic_read( &(pmm->messages_queued) ); while( process_messages > 0 ) { /* Check internal message queue first */ err = _mali_osk_notification_queue_dequeue( pmm->iqueue, &msg ); if( err != _MALI_OSK_ERR_OK ) { if( pmm->status == MALI_PMM_STATUS_IDLE || pmm->status == MALI_PMM_STATUS_OS_WAITING || pmm->status == MALI_PMM_STATUS_DVFS_PAUSE) { if( pmm->waiting > 0 ) pmm->waiting--; /* We aren't busy changing state, so look at real events */ err = _mali_osk_notification_queue_dequeue( pmm->queue, &msg ); if( err != _MALI_OSK_ERR_OK ) { pmm->no_events++; MALIPMM_DEBUG_PRINT( ("PMM: event_process - No message to process\n") ); /* Nothing to do - so return */ return; } else { #if MALI_PMM_TRACE pmm->messages_received++; #endif } } else { /* Waiting for an internal message */ pmm->waiting++; MALIPMM_DEBUG_PRINT( ("PMM: event_process - Waiting for internal message, messages queued=%d\n", pmm->waiting) ); return; } } else { #if MALI_PMM_TRACE pmm->imessages_received++; #endif } MALI_DEBUG_ASSERT_POINTER( msg ); /* Check the message type matches */ MALI_DEBUG_ASSERT( msg->notification_type == MALI_PMM_NOTIFICATION_TYPE ); event = msg->result_buffer; _mali_osk_atomic_dec( &(pmm->messages_queued) ); process_messages--; #if MALI_PMM_TRACE /* Trace before we process the event in case we have an error */ _mali_pmm_trace_event_message( event, MALI_TRUE ); #endif err = pmm_policy_process( pmm, event ); if( err != _MALI_OSK_ERR_OK ) { MALI_PRINT_ERROR( ("PMM: Error(%d) in policy %d when processing event message with id: %d", err, pmm->policy, event->id) ); } /* Delete notification */ _mali_osk_notification_delete ( msg ); if( pmm->fatal_power_err ) { /* Nothing good has happened - exit */ return; } #if MALI_PMM_TRACE MALI_PRINT( ("PMM Trace: Event processed, msgs (sent/read) = %d/%d, int msgs (sent/read) = %d/%d, no events = %d, waiting = %d\n", pmm->messages_sent, pmm->messages_received, pmm->imessages_sent, pmm->imessages_received, pmm->no_events, pmm->waiting) ); #endif } if( pmm->status == MALI_PMM_STATUS_IDLE && pmm->waiting > 0 ) { /* For events we ignored whilst we were busy, add a new * scheduled time to look at them */ _mali_osk_irq_schedulework( pmm->irq ); } }