static void mali_dvfs_handler(struct work_struct *work)
{
    /*unsigned long flags;*/
    int           enabled;
    int           duration;
    int           boostID;
    int           perfID;
    int           gedID;
    int           halID;
    int           targetID;

    if (0 == atomic_read(&g_is_power_enabled))
    {
        MALI_DEBUG_PRINT(4, ("GPU clock is switching down\n"));
        return;
    }

    // Get related settings
    enabled  = mtk_get_input_boost_enabled();
    duration = mtk_get_input_boost_duration();
    boostID  = mtk_get_boost_frequency_id();
    perfID   = mtk_get_perf_hal_frequency_id();
    gedID    = mtk_get_ged_hal_frequency_id();
    targetID = mtk_get_current_frequency_id();

    if ((enabled != 0) && (duration > 0))
    {
        targetID = boostID;
    }
    else
    {
        if (targetID < mt_gpufreq_get_thermal_limit_index())
        {
            targetID = mt_gpufreq_get_thermal_limit_index();
        }

        /* Calculate higher boost frequency (e.g. lower index id) */
        if(perfID < gedID)
        {
            halID = perfID;
        }
        else
        {
            halID = gedID;
        }
    
        if(targetID > halID)
        {
            MALI_DEBUG_PRINT(4, ("Use GPU boost frequency %d as target!\n", halID));
            targetID = halID;
        }
    }

    if (targetID != mt_gpufreq_get_cur_freq_index())
    {
        mt_gpufreq_target(targetID);
    }
}
Beispiel #2
0
bool ged_dvfs_gpu_freq_commit(unsigned long ui32NewFreqID, GED_DVFS_COMMIT_TYPE eCommitType)
{
	int bCommited=false;
#ifdef GED_DVFS_ENABLE    
	unsigned long ui32CurFreqID;
	ui32CurFreqID = mt_gpufreq_get_cur_freq_index();
	if (NULL != ged_dvfs_gpu_freq_commit_fp)
	{

		if (ui32NewFreqID > g_bottom_freq_id)
		{
			ui32NewFreqID = g_bottom_freq_id;
		}
		if (ui32NewFreqID > g_cust_boost_freq_id)
		{
			ui32NewFreqID = g_cust_boost_freq_id;
		}

		// up bound
		if (ui32NewFreqID < g_cust_upbound_freq_id)
		{
			ui32NewFreqID = g_cust_upbound_freq_id;
		}

		// thermal power limit
		if (ui32NewFreqID < mt_gpufreq_get_thermal_limit_index())
		{
			ui32NewFreqID = mt_gpufreq_get_thermal_limit_index();
		}

		// do change
		if (ui32NewFreqID != ui32CurFreqID)
		{
			// call to DVFS module
			ged_dvfs_gpu_freq_commit_fp(ui32NewFreqID, eCommitType, &bCommited);
			/* 
			 * To-Do: refine previous freq contributions, 
			 * since it is possible to have multiple freq settings in previous execution period
			 * Does this fatal for precision?
			 */
			ged_log_buf_print(ghLogBuf_DVFS, "[GED_K] new freq ID commited: idx=%lu type=%u",ui32NewFreqID, eCommitType);
			if(true==bCommited)
			{
				ged_log_buf_print(ghLogBuf_DVFS, "[GED_K] commited true");
				g_ui32PreFreqID = ui32CurFreqID;            
			}
		}	
	}
#endif    
	return bCommited;
}
/* this function will be called periodically with sampling period 200ms~1000ms */
void mali_pmm_utilization_handler(struct mali_gpu_utilization_data *data)
{    
    int              utilization;
    mali_dvfs_action action;
    int              frequency;
    int              duration;
    int              currentID;
    int              targetID;
    int              deferred;

    mali_utilization = data->utilization_gpu;
    
    if (0 == atomic_read(&g_is_power_enabled))
        
    {
        MALI_DEBUG_PRINT(4, ("GPU clock is in off state\n"));
        return;
    }

    utilization = (mali_utilization * 100) / 256;

    MALI_DEBUG_PRINT(4, ("%s GPU utilization=%d\n", __FUNCTION__, utilization));

    if (utilization <= mtk_get_dvfs_threshold_min())
    {
        action = MALI_DVFS_CLOCK_DOWN;
    }
    else if (utilization >= mtk_get_dvfs_threshold_max())
    {
        action = MALI_DVFS_CLOCK_UP;
    }
    else
    {
        MALI_DEBUG_PRINT(4, ("No need to adjust GPU frequency!\n"));
        return;
    }

    // Get current frequency id    
    currentID = mt_gpufreq_get_cur_freq_index();

    // Get current deferred count
    deferred  = mtk_get_current_deferred_count();

    switch(action)
    {
        case MALI_DVFS_CLOCK_UP:
            frequency = mapIndexToFrequency(currentID) * utilization / mtk_get_dvfs_threshold_min();
            targetID  = mapFrequencyToIndex(frequency);
            deferred += 1;
            break;
        case MALI_DVFS_CLOCK_DOWN:
            frequency = mapIndexToFrequency(currentID) * utilization / mtk_get_dvfs_threshold_max();
            targetID  = mapFrequencyToIndex(frequency);
            deferred += 1;
            break;
        default:
            MALI_DEBUG_PRINT(4, ("Unknown GPU DVFS operation!\n"));
            return;
    }

    // Thermal power limit
    if (targetID < mt_gpufreq_get_thermal_limit_index())
    {
        targetID = mt_gpufreq_get_thermal_limit_index();
    }

    duration = mtk_get_input_boost_duration();
    if((duration > 0) && (mtk_get_input_boost_enabled() != 0))
    {
        MALI_DEBUG_PRINT(4, ("Still in the boost duration!\n"));
        
        mtk_set_input_boost_duration(duration - 1);
        
        if (targetID >= mtk_get_boost_frequency_id())
        {
            mtk_set_current_deferred_count(deferred);
            return;
        }
    }
    else if (deferred < mtk_get_dvfs_deferred_count())
    {
        MALI_DEBUG_PRINT(4, ("Defer DVFS frequency operation!\n"));
        mtk_set_current_deferred_count(deferred);             
        return;
    }

    if(currentID == targetID)
    {
        MALI_DEBUG_PRINT(4, ("Target GPU frequency is the same!\n"));
        return;
    }

    if (targetID < 0)
    {
        targetID = 0;
    }
    else if (targetID >= mt_gpufreq_get_dvfs_table_num())
    {
        targetID = mt_gpufreq_get_dvfs_table_num() - 1;
    }

    mtk_set_current_frequency_id(targetID);
    
    if (targetID < mtk_get_boost_frequency_id())
    {
        mtk_set_boost_frequency_id(targetID);
    }

    mtk_set_current_deferred_count(0);

#if MALI_LICENSE_IS_GPL
    if (mali_dvfs_queue && (1 == atomic_read(&g_is_power_enabled)))
    {
        queue_work(mali_dvfs_queue, &mali_dvfs_work);
    }
#endif // MALI_LICENSE_IS_GPL
}