_mali_osk_errcode_t mali_pmu_power_down(struct mali_pmu_core *pmu, u32 mask) { u32 stat; _mali_osk_errcode_t err; MALI_DEBUG_ASSERT_POINTER(pmu); MALI_DEBUG_ASSERT(pmu->registered_cores_mask != 0); MALI_DEBUG_ASSERT(mask <= pmu->registered_cores_mask); MALI_DEBUG_ASSERT(0 == (mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_RAWSTAT) & PMU_REG_VAL_IRQ)); MALI_DEBUG_PRINT(3, ("PMU power down: ...................... [%s]\n", mali_pm_mask_to_string(mask))); stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS); /* * Assert that we are not powering down domains which are already * powered down. */ MALI_DEBUG_ASSERT(0 == (stat & mask)); mask &= ~(0x1 << MALI_DOMAIN_INDEX_DUMMY); 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() || mali_is_mali470() || 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) /* Verify power status of domains after power down */ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS); MALI_DEBUG_ASSERT(mask == (stat & mask)); #endif return _MALI_OSK_ERR_OK; }
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; }