static _mali_osk_errcode_t mali_pp_upper_half(void *data) { struct mali_pp_core *core = (struct mali_pp_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, MALI200_REG_ADDR_MGMT_INT_STATUS); #if MALI_SHARED_INTERRUPTS } mali_pm_unlock(); #endif if (MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout) { mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_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_PP(core->core_id)|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; }
void mali_gp_hard_reset(struct mali_gp_core *core) { const u32 reset_wait_target_register = MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW; const u32 reset_invalid_value = 0xC0FFE000; const u32 reset_check_value = 0xC01A0000; const u32 reset_default_value = 0; int i; MALI_DEBUG_ASSERT_POINTER(core); MALI_DEBUG_PRINT(4, ("Mali GP: Hard reset of core %s\n", core->hw_core.description)); mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_invalid_value); mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_RESET); for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) { mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_check_value); if (reset_check_value == mali_hw_core_register_read(&core->hw_core, reset_wait_target_register)) { break; } } if (MALI_REG_POLL_COUNT_FAST == i) { MALI_PRINT_ERROR(("Mali GP: The hard reset loop didn't work, unable to recover\n")); } mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_default_value); /* set it back to the default */ /* Re-enable interrupts */ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); }
_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core) { int i; MALI_DEBUG_ASSERT_POINTER(core); /* Send the stop bus command. */ mali_gp_stop_bus(core); /* Wait for bus to be stopped */ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) { if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED) { break; } } if (MALI_REG_POLL_COUNT_FAST == i) { MALI_PRINT_ERROR(("Mali GP: Failed to stop bus on %s\n", core->hw_core.description)); return _MALI_OSK_ERR_FAULT; } return _MALI_OSK_ERR_OK; }
/* ------------- 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; #if !defined(MSTAR_RIU_ENABLED) || (MSTAR_RIU_ADDRESS_TYPE == 32) irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT); #else irq_readout = mali_hw_core_register_read_no_lock(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT); #endif if (MALIGP2_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, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE); #else mali_hw_core_register_write_no_lock(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_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_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; }
static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core *cache, u32 reg, u32 val) { int i = 0; const int loop_count = 100000; /* * Grab lock in order to send commands to the L2 cache in a serialized fashion. * The L2 cache will ignore commands if it is busy. */ _mali_osk_lock_wait(cache->command_lock, _MALI_OSK_LOCKMODE_RW); /* First, wait for L2 cache command handler to go idle */ for (i = 0; i < loop_count; i++) { if (!(mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_STATUS) & (u32)MALI400_L2_CACHE_STATUS_COMMAND_BUSY)) { break; } } if (i == loop_count) { _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW); MALI_DEBUG_PRINT(1, ( "Mali L2 cache: aborting wait for command interface to go idle\n")); MALI_ERROR( _MALI_OSK_ERR_FAULT ); } /* then issue the command */ mali_hw_core_register_write(&cache->hw_core, reg, val); _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW); MALI_SUCCESS; }
void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr) { u32 irq_readout; MALI_DEBUG_ASSERT_POINTER(core); MALI_ASSERT_GROUP_LOCKED(core->group); irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT); if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM) { mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG)); mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* re-enable interrupts */ mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, start_addr); mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, end_addr); MALI_DEBUG_PRINT(3, ("Mali GP: Resuming job\n")); mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC); _mali_osk_write_mem_barrier(); #if MALI_TIMELINE_PROFILING_ENABLED _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), 0, 0, 0, 0, 0); #endif } /* * else: core has been reset between PLBU_OUT_OF_MEM interrupt and this new heap response. * A timeout or a page fault on Mali-200 PP core can cause this behaviour. */ }
_mali_osk_errcode_t mali_pp_reset_wait(struct mali_pp_core *core) { int i; u32 rawstat = 0; /* TODO: For virtual Mali-450 core, check that PP active in STATUS is 0 (this must be initiated from group) */ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) { rawstat = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT); if (rawstat & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED) { break; } } if (i == MALI_REG_POLL_COUNT_FAST) { MALI_PRINT_ERROR(("Mali PP: Failed to reset core %s, rawstat: 0x%08x\n", core->hw_core.description, rawstat)); return _MALI_OSK_ERR_FAULT; } /* Re-enable interrupts */ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL); mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); return _MALI_OSK_ERR_OK; }
_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core) { int i; MALI_DEBUG_ASSERT_POINTER(core); MALI_DEBUG_PRINT(2,("mali_pp_stop_bus_wait: core->hw_core %s\n", core->hw_core.description)); /// try power on the mali driver for recovery mali_platform_power_mode_change(MALI_POWER_MODE_ON); /* Send the stop bus command. */ mali_pp_stop_bus(core); /* Wait for bus to be stopped */ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) { if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED) break; } if (MALI_REG_POLL_COUNT_FAST == i) { 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))); return _MALI_OSK_ERR_FAULT; } return _MALI_OSK_ERR_OK; }
_mali_osk_errcode_t mali_pp_reset_wait(struct mali_pp_core *core) { int i; u32 rawstat = 0; for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) { if (!(mali_pp_read_status(core) & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE)) { rawstat = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT); if (rawstat == MALI400PP_REG_VAL_IRQ_RESET_COMPLETED) { break; } } } if (i == MALI_REG_POLL_COUNT_FAST) { MALI_PRINT_ERROR(("Mali PP: Failed to reset core %s, rawstat: 0x%08x\n", core->hw_core.description, rawstat)); return _MALI_OSK_ERR_FAULT; } /* Re-enable interrupts */ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL); mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); return _MALI_OSK_ERR_OK; }
static void mali_pp_print_registers(struct mali_pp_core *core) { 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))); 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))); 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))); 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))); 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))); 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))); 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))); 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))); 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))); 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))); 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))); 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))); 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))); }
_mali_osk_errcode_t mali_gp_reset_wait(struct mali_gp_core *core) { int i; u32 rawstat = 0; MALI_DEBUG_ASSERT_POINTER(core); for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++) { rawstat = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT); if (rawstat & MALI400GP_REG_VAL_IRQ_RESET_COMPLETED) { break; } } if (i == MALI_REG_POLL_COUNT_FAST) { MALI_PRINT_ERROR(("Mali GP: Failed to reset core %s, rawstat: 0x%08x\n", core->hw_core.description, rawstat)); return _MALI_OSK_ERR_FAULT; } /* Re-enable interrupts */ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); return _MALI_OSK_ERR_OK; }
_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core) { int i; const int request_loop_count = 20; MALI_DEBUG_ASSERT_POINTER(core); MALI_ASSERT_GROUP_LOCKED(core->group); /* Send the stop bus command. */ mali_pp_stop_bus(core); /* Wait for bus to be stopped */ for (i = 0; i < request_loop_count; i++) { if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED) break; _mali_osk_time_ubusydelay(10); } if (request_loop_count == i) { 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))); return _MALI_OSK_ERR_FAULT; } return _MALI_OSK_ERR_OK; }
void mali_dlbu_disable(struct mali_dlbu_core *dlbu) { u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR); wval |= (wval & 0xFFFFFFFE); mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, wval); }
/* Is called when the irq probe wants the mmu to acknowledge an interrupt from the hw */ static _mali_osk_errcode_t mali_mmu_probe_ack(void *data) { struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; u32 int_stat; int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS); MALI_DEBUG_PRINT(2, ("mali_mmu_probe_irq_acknowledge: intstat 0x%x\n", int_stat)); if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT) { MALI_DEBUG_PRINT(2, ("Probe: Page fault detect: PASSED\n")); mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_PAGE_FAULT); } else { MALI_DEBUG_PRINT(1, ("Probe: Page fault detect: FAILED\n")); } if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR) { MALI_DEBUG_PRINT(2, ("Probe: Bus read error detect: PASSED\n")); mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR); } else { MALI_DEBUG_PRINT(1, ("Probe: Bus read error detect: FAILED\n")); } if ((int_stat & (MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR)) == (MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR)) { return _MALI_OSK_ERR_OK; } return _MALI_OSK_ERR_FAULT; }
_mali_osk_errcode_t mali_pmu_powerdown_all(struct mali_pmu_core *pmu) { u32 stat; u32 timeout; MALI_DEBUG_ASSERT_POINTER(pmu); MALI_DEBUG_ASSERT( pmu->mali_registered_cores_power_mask != 0 ); MALI_DEBUG_PRINT( 4, ("Mali PMU: power down (0x%08X)\n", pmu->mali_registered_cores_power_mask) ); mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_DOWN, pmu->mali_registered_cores_power_mask); /* Wait for cores to be powered down (100 x 100us = 100ms) */ timeout = MALI_REG_POLL_COUNT_SLOW ; do { /* Get status of sleeping cores */ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS); stat &= pmu->mali_registered_cores_power_mask; if( stat == pmu->mali_registered_cores_power_mask ) break; /* All cores we wanted are now asleep */ timeout--; } while( timeout > 0 ); if( timeout == 0 ) { return _MALI_OSK_ERR_TIMEOUT; } return _MALI_OSK_ERR_OK; }
static _mali_osk_errcode_t mali_pmu_power_up_internal(struct mali_pmu_core *pmu, const u32 mask) { u32 stat; _mali_osk_errcode_t err; #if !defined(CONFIG_MALI_PMU_PARALLEL_POWER_UP) u32 current_domain; #endif MALI_DEBUG_ASSERT_POINTER(pmu); MALI_DEBUG_ASSERT(0 == (mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_RAWSTAT) & PMU_REG_VAL_IRQ)); stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS); stat &= pmu->registered_cores_mask; if (0 == mask || 0 == (stat & mask)) return _MALI_OSK_ERR_OK; #if defined(CONFIG_MALI_PMU_PARALLEL_POWER_UP) mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_UP, mask); err = mali_pmu_wait_for_command_finish(pmu); if (_MALI_OSK_ERR_OK != err) { return err; } #else for (current_domain = 1; current_domain <= pmu->registered_cores_mask; current_domain <<= 1) { if (current_domain & mask & stat) { mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_UP, current_domain); err = mali_pmu_wait_for_command_finish(pmu); if (_MALI_OSK_ERR_OK != err) { return err; } } } #endif #if defined(DEBUG) /* Get power status of cores */ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS); stat &= pmu->registered_cores_mask; MALI_DEBUG_ASSERT(0 == (stat & mask)); MALI_DEBUG_ASSERT(0 == (stat & pmu->active_cores_mask)); #endif /* defined(DEBUG) */ return _MALI_OSK_ERR_OK; }
mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu) { int i; u32 mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED) ) { MALI_DEBUG_PRINT(4, ("MMU stall is implicit when Paging is not enebled.\n")); return MALI_TRUE; } if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE ) { MALI_DEBUG_PRINT(3, ("Aborting MMU stall request since it is in pagefault state.\n")); return MALI_FALSE; } mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL); for (i = 0; i < MALI_REG_POLL_COUNT_SLOW; ++i) { mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); if (mmu_status & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) && (0 == (mmu_status & MALI_MMU_STATUS_BIT_STALL_NOT_ACTIVE))) { break; } if (0 == (mmu_status & ( MALI_MMU_STATUS_BIT_PAGING_ENABLED ))) { break; } } if (MALI_REG_POLL_COUNT_SLOW == i) { MALI_PRINT_ERROR(("Enable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); return MALI_FALSE; } if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE ) { MALI_DEBUG_PRINT(3, ("Aborting MMU stall request since it has a pagefault.\n")); return MALI_FALSE; } return MALI_TRUE; }
static void mali_dma_bus_error(struct mali_dma_core *dma) { u32 addr = mali_hw_core_register_read(&dma->hw_core, MALI450_DMA_REG_SOURCE_ADDRESS); MALI_PRINT_ERROR(("Mali DMA: Bus error when reading command list from 0x%lx\n", addr)); /* Clear the bus error */ mali_hw_core_register_write(&dma->hw_core, MALI450_DMA_REG_SOURCE_SIZE, 0); }
static void mali_mmu_enable_paging(struct mali_mmu_core *mmu) { int i; mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING); for (i = 0; i < MALI_REG_POLL_COUNT_FAST; ++i) { if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED) { break; } } if (MALI_REG_POLL_COUNT_FAST == i) { MALI_PRINT_ERROR(("Enable paging request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); } }
static void mali_mmu_activate_address_space(struct mali_mmu_core *mmu, u32 page_directory) { /* The MMU must be in stalled or page fault mode, for this writing to work */ MALI_DEBUG_ASSERT(0 != (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS) & (MALI_MMU_STATUS_BIT_STALL_ACTIVE | MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE))); mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, page_directory); mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); }
static _mali_osk_errcode_t mali_mmu_upper_half(void * data) { struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; u32 int_stat = 0; MALI_DEBUG_ASSERT_POINTER(mmu); #if MALI_SHARED_INTERRUPTS mali_pm_lock(); if (MALI_TRUE == mali_pm_is_powered_on()) { #endif /* 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 MALI_SHARED_INTERRUPTS } mali_pm_unlock(); #endif 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; }
void mali_mmu_disable_stall(struct mali_mmu_core *mmu) { const int max_loop_count = 100; const int delay_in_usecs = 1; int i; u32 mmu_status; /* There are no group when it is called from mali_mmu_create */ if ( mmu->group ) MALI_ASSERT_GROUP_LOCKED(mmu->group); mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED )) { MALI_DEBUG_PRINT(3, ("MMU disable skipped since it was not enabled.\n")); return; } if (mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) { MALI_DEBUG_PRINT(2, ("Aborting MMU disable stall request since it is in pagefault state.\n")); return; } mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL); for (i = 0; i < max_loop_count; ++i) { u32 status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); if ( 0 == (status & MALI_MMU_STATUS_BIT_STALL_ACTIVE) ) { break; } if ( status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE ) { break; } if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED )) { break; } _mali_osk_time_ubusydelay(delay_in_usecs); } if (max_loop_count == i) MALI_DEBUG_PRINT(1,("Disable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); }
_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu) { _mali_osk_errcode_t err; u32 cores_off_mask, cores_on_mask, stat; mali_pmu_lock(pmu); /* Setup the desired defaults */ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0); mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_SW_DELAY, pmu->switch_delay); /* Get power status of cores */ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS); cores_off_mask = pmu->registered_cores_mask & ~(stat | pmu->active_cores_mask); cores_on_mask = pmu->registered_cores_mask & (stat & pmu->active_cores_mask); if (0 != cores_off_mask) { err = mali_pmu_send_command_internal(pmu, PMU_REG_ADDR_MGMT_POWER_DOWN, cores_off_mask); if (_MALI_OSK_ERR_OK != err) return err; } if (0 != cores_on_mask) { err = mali_pmu_send_command_internal(pmu, PMU_REG_ADDR_MGMT_POWER_UP, cores_on_mask); if (_MALI_OSK_ERR_OK != err) return err; } #if defined(DEBUG) { stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS); stat &= pmu->registered_cores_mask; MALI_DEBUG_ASSERT(stat == (pmu->registered_cores_mask & ~pmu->active_cores_mask)); } #endif /* defined(DEBUG) */ mali_pmu_unlock(pmu); return _MALI_OSK_ERR_OK; }
MALI_STATIC_INLINE _mali_osk_errcode_t mali_mmu_raw_reset(struct mali_mmu_core *mmu) { int i; mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE); MALI_DEBUG_ASSERT(0xCAFEB000 == mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR)); mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_HARD_RESET); for (i = 0; i < MALI_REG_POLL_COUNT_FAST; ++i) { if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR) == 0) { break; } } if (MALI_REG_POLL_COUNT_FAST == i) { MALI_PRINT_ERROR(("Reset request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); return _MALI_OSK_ERR_FAULT; } return _MALI_OSK_ERR_OK; }
static void mali_mmu_bottom_half(void * data) { struct mali_mmu_core *mmu = (struct mali_mmu_core*)data; u32 raw, status, fault_address; MALI_DEBUG_ASSERT_POINTER(mmu); MALI_DEBUG_PRINT(3, ("Mali MMU: Page fault bottom half: Locking subsystems\n")); mali_group_lock(mmu->group); /* Unlocked in mali_group_bottom_half */ if ( MALI_FALSE == mali_group_power_is_on(mmu->group) ) { MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.",mmu->hw_core.description)); mali_group_unlock(mmu->group); return; } raw = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT); status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); if ( (0==(raw & MALI_MMU_INTERRUPT_PAGE_FAULT)) && (0==(status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)) ) { MALI_DEBUG_PRINT(2, ("Mali MMU: Page fault bottom half: No Irq found.\n")); mali_group_unlock(mmu->group); /* MALI_DEBUG_ASSERT(0); */ return; } /* An actual page fault has occurred. */ fault_address = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_PAGE_FAULT_ADDR); MALI_DEBUG_PRINT(2,("Mali MMU: Page fault detected at 0x%x from bus id %d of type %s on %s\n", (void*)fault_address, (status >> 6) & 0x1F, (status & 32) ? "write" : "read", mmu->hw_core.description)); mali_group_bottom_half(mmu->group, GROUP_EVENT_MMU_PAGE_FAULT); /* Unlocks the group lock */ }
static void mali_mmu_enable_paging(struct mali_mmu_core *mmu) { const int max_loop_count = 100; const int delay_in_usecs = 1; int i; mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING); for (i = 0; i < max_loop_count; ++i) { if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED) { break; } _mali_osk_time_ubusydelay(delay_in_usecs); } if (max_loop_count == i) { MALI_PRINT_ERROR(("Enable paging request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); } }
static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data) { struct mali_pp_core *core = (struct mali_pp_core *)data; u32 irq_readout; irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS); if (MALI200_REG_VAL_IRQ_BUS_ERROR & irq_readout) { mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_BUS_ERROR); _mali_osk_mem_barrier(); return _MALI_OSK_ERR_OK; } return _MALI_OSK_ERR_FAULT; }
void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu) { /* this function to implement (see documentation): * 1) clear all bits in the enable register * 2) wait until all PPs have finished - mali_pp_scheduler.c code - this done in interrupts call? * 3) read the current tile position registers to get current tile positions - * note that current tile position register is the same as start tile position - perhaps the name should be changed!!! */ /* 1) */ mali_dlbu_disable_all_pp_cores(dlbu); /* 3) */ mali_dlbu_tile_position = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS); }
static _mali_osk_errcode_t mali_pmu_power_down_internal(struct mali_pmu_core *pmu, const u32 mask) { u32 stat; _mali_osk_errcode_t err; MALI_DEBUG_ASSERT_POINTER(pmu); MALI_DEBUG_ASSERT(0 == (mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_RAWSTAT) & PMU_REG_VAL_IRQ)); stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS); stat &= pmu->registered_cores_mask; if (0 == mask || 0 == ((~stat) & mask)) return _MALI_OSK_ERR_OK; mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_DOWN, mask); /* Do not wait for interrupt on Mali-300/400 if all domains are powered off * by our power down command, because the HW will simply not generate an * interrupt in this case.*/ if (mali_is_mali450() || pmu->registered_cores_mask != (mask | stat)) { err = mali_pmu_wait_for_command_finish(pmu); if (_MALI_OSK_ERR_OK != err) { return err; } } else { mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_CLEAR, PMU_REG_VAL_IRQ); } #if defined(DEBUG) /* Get power status of cores */ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS); stat &= pmu->registered_cores_mask; MALI_DEBUG_ASSERT(mask == (stat & mask)); #endif return _MALI_OSK_ERR_OK; }
void mali_mmu_disable_stall(struct mali_mmu_core *mmu) { int i; u32 mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED )) { MALI_DEBUG_PRINT(3, ("MMU disable skipped since it was not enabled.\n")); return; } if (mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) { MALI_DEBUG_PRINT(2, ("Aborting MMU disable stall request since it is in pagefault state.\n")); return; } mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL); for (i = 0; i < MALI_REG_POLL_COUNT_FAST; ++i) { u32 status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); if ( 0 == (status & MALI_MMU_STATUS_BIT_STALL_ACTIVE) ) { break; } if ( status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE ) { break; } if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED )) { break; } } if (MALI_REG_POLL_COUNT_FAST == i) MALI_DEBUG_PRINT(1,("Disable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); }