static unsigned int decideNextStatus(unsigned int utilization) { static unsigned int level = 0; // 0:stay, 1:up static int mali_dvfs_clk = 0; if (mali_runtime_resumed >= 0) { level = mali_runtime_resumed; mali_runtime_resumed = -1; } if (mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold <= mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold) { MALI_PRINT(("upthreadshold is smaller than downthreshold: %d < %d\n", mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold, mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold)); return level; } if (!mali_dvfs_control && level == maliDvfsStatus.currentStep) { if (utilization > (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold / 100) && level < MALI_DVFS_STEPS - 1) { level++; } if (utilization < (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold / 100) && level > 0) { level--; } } else if (mali_dvfs_control == 999) { int i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { step[i].clk = mali_dvfs_all[i].clock; } #ifdef EXYNOS4_ASV_ENABLED //mali_dvfs_table_update(); #endif i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { mali_dvfs[i].clock = step[i].clk; } mali_dvfs_control = 0; level = 0; step0_clk = step[0].clk; change_dvfs_tableset(step0_clk, 0); #if (MALI_DVFS_STEPS > 1) step1_clk = step[1].clk; change_dvfs_tableset(step1_clk, 1); #if (MALI_DVFS_STEPS > 2) step2_clk = step[2].clk; change_dvfs_tableset(step2_clk, 2); #if (MALI_DVFS_STEPS > 3) step3_clk = step[3].clk; change_dvfs_tableset(step3_clk, 3); #endif #endif #endif } else if (mali_dvfs_control != mali_dvfs_clk && mali_dvfs_control != 999) { if (mali_dvfs_control < mali_dvfs_all[1].clock && mali_dvfs_control > 0) { int i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { step[i].clk = mali_dvfs_all[0].clock; } maliDvfsStatus.currentStep = 0; } else if (mali_dvfs_control < mali_dvfs_all[2].clock && mali_dvfs_control >= mali_dvfs_all[1].clock) { int i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { step[i].clk = mali_dvfs_all[1].clock; } maliDvfsStatus.currentStep = 1; } else if (mali_dvfs_control < mali_dvfs_all[3].clock && mali_dvfs_control >= mali_dvfs_all[2].clock) { int i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { step[i].clk = mali_dvfs_all[2].clock; } maliDvfsStatus.currentStep = 2; } else { int i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { step[i].clk = mali_dvfs_all[3].clock; } maliDvfsStatus.currentStep = 3; } step0_clk = step[0].clk; change_dvfs_tableset(step0_clk, 0); #if (MALI_DVFS_STEPS > 1) step1_clk = step[1].clk; change_dvfs_tableset(step1_clk, 1); #if (MALI_DVFS_STEPS > 2) step2_clk = step[2].clk; change_dvfs_tableset(step2_clk, 2); #if (MALI_DVFS_STEPS > 3) step3_clk = step[3].clk; change_dvfs_tableset(step3_clk, 3); #endif #endif #endif level = maliDvfsStatus.currentStep; } mali_dvfs_clk = mali_dvfs_control; return level; }
static void mali_dvfs_work_handler(struct work_struct *w) { int change_clk = 0; int change_step = 0; bMaliDvfsRun=1; /* dvfs table change when clock was changed */ if (step0_clk != mali_dvfs[0].clock) { MALI_PRINT(("::: step0_clk change to %d Mhz\n", step0_clk)); change_clk = step0_clk; change_step = 0; step0_clk = change_dvfs_tableset(change_clk, change_step); } #if (MALI_DVFS_STEPS > 1) if (step1_clk != mali_dvfs[1].clock) { MALI_PRINT(("::: step1_clk change to %d Mhz\n", step1_clk)); change_clk = step1_clk; change_step = 1; step1_clk = change_dvfs_tableset(change_clk, change_step); } if (step0_up != mali_dvfs_threshold[0].upthreshold) { MALI_PRINT(("::: step0_up change to %d %\n", step0_up)); mali_dvfs_threshold[0].upthreshold = step0_up; } if (step1_down != mali_dvfs_threshold[1].downthreshold) { MALI_PRINT((":::step1_down change to %d %\n", step1_down)); mali_dvfs_threshold[1].downthreshold = step1_down; } #if (MALI_DVFS_STEPS > 2) if (step2_clk != mali_dvfs[2].clock) { MALI_PRINT(("::: step2_clk change to %d Mhz\n", step2_clk)); change_clk = step2_clk; change_step = 2; step2_clk = change_dvfs_tableset(change_clk, change_step); } if (step1_up != mali_dvfs_threshold[1].upthreshold) { MALI_PRINT((":::step1_up change to %d %\n", step1_up)); mali_dvfs_threshold[1].upthreshold = step1_up; } if (step2_down != mali_dvfs_threshold[2].downthreshold) { MALI_PRINT((":::step2_down change to %d %\n", step2_down)); mali_dvfs_threshold[2].downthreshold = step2_down; } #if (MALI_DVFS_STEPS > 3) if (step3_clk != mali_dvfs[3].clock) { MALI_PRINT(("::: step3_clk change to %d Mhz\n", step3_clk)); change_clk = step3_clk; change_step = 3; step3_clk = change_dvfs_tableset(change_clk, change_step); } if (step2_up != mali_dvfs_threshold[2].upthreshold) { MALI_PRINT((":::step2_up change to %d %\n", step2_up)); mali_dvfs_threshold[2].upthreshold = step2_up; } if (step3_down != mali_dvfs_threshold[3].downthreshold) { MALI_PRINT((":::step3_down change to %d %\n", step3_down)); mali_dvfs_threshold[3].downthreshold = step3_down; } #endif #endif #endif #ifdef DEBUG mali_dvfs[0].vol = step0_vol; mali_dvfs[1].vol = step1_vol; mali_dvfs[2].vol = step2_vol; mali_dvfs[3].vol = step3_vol; #endif MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n")); if (!mali_dvfs_status(mali_dvfs_utilization)) MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler")); bMaliDvfsRun=0; }
static unsigned int decideNextStatus(unsigned int utilization) { static unsigned int level = 0; // 0:stay, 1:up static int mali_dvfs_clk = 0; if (mali_runtime_resumed >= 0) { level = mali_runtime_resumed; mali_runtime_resumed = -1; return level; } if (mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold <= mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold) { MALI_PRINT(("upthreadshold is smaller than downthreshold: %d < %d\n", mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold, mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold)); return level; } if (!mali_dvfs_control && level == maliDvfsStatus.currentStep) { if (utilization > (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold / 100) && level < MALI_DVFS_STEPS - 1) { level++; // this prevents the usage of 5th step -gm // if ((samsung_rev() < EXYNOS4412_REV_2_0) && (maliDvfsStatus.currentStep == 3)) { // level=get_mali_dvfs_status(); // } } if (utilization < (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold / 100) && level > 0) { level--; } } else if (mali_dvfs_control == 999) { int i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { step[i].clk = mali_dvfs_all[i].clock; } #ifdef EXYNOS4_ASV_ENABLED // mali_dvfs_table_update(); #endif i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { mali_dvfs[i].clock = step[i].clk; } mali_dvfs_control = 0; level = 0; step0_clk = step[0].clk; change_dvfs_tableset(step0_clk, 0); #if (MALI_DVFS_STEPS > 1) step1_clk = step[1].clk; change_dvfs_tableset(step1_clk, 1); #if (MALI_DVFS_STEPS > 2) step2_clk = step[2].clk; change_dvfs_tableset(step2_clk, 2); #if (MALI_DVFS_STEPS > 3) step3_clk = step[3].clk; change_dvfs_tableset(step3_clk, 3); #if (MALI_DVFS_STEPS > 4) step4_clk = step[4].clk; change_dvfs_tableset(step4_clk, 4); #endif #endif #endif #endif } else if (mali_dvfs_control != mali_dvfs_clk && mali_dvfs_control != 999) { if (mali_dvfs_control < mali_dvfs_all[1].clock && mali_dvfs_control > 0) { int i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { step[i].clk = mali_dvfs_all[0].clock; } maliDvfsStatus.currentStep = 0; } else if (mali_dvfs_control < mali_dvfs_all[2].clock && mali_dvfs_control >= mali_dvfs_all[1].clock) { int i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { step[i].clk = mali_dvfs_all[1].clock; } maliDvfsStatus.currentStep = 1; } else if (mali_dvfs_control < mali_dvfs_all[3].clock && mali_dvfs_control >= mali_dvfs_all[2].clock) { int i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { step[i].clk = mali_dvfs_all[2].clock; } maliDvfsStatus.currentStep = 2; } else if (mali_dvfs_control < mali_dvfs_all[4].clock && mali_dvfs_control >= mali_dvfs_all[3].clock) { int i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { step[i].clk = mali_dvfs_all[3].clock; } maliDvfsStatus.currentStep = 3; } else { int i = 0; for (i = 0; i < MALI_DVFS_STEPS; i++) { step[i].clk = mali_dvfs_all[4].clock; } maliDvfsStatus.currentStep = 4; } step0_clk = step[0].clk; change_dvfs_tableset(step0_clk, 0); #if (MALI_DVFS_STEPS > 1) step1_clk = step[1].clk; change_dvfs_tableset(step1_clk, 1); #if (MALI_DVFS_STEPS > 2) step2_clk = step[2].clk; change_dvfs_tableset(step2_clk, 2); #if (MALI_DVFS_STEPS > 3) step3_clk = step[3].clk; change_dvfs_tableset(step3_clk, 3); #if (MALI_DVFS_STEPS > 4) step4_clk = step[4].clk; change_dvfs_tableset(step4_clk, 4); #endif #endif #endif #endif level = maliDvfsStatus.currentStep; } mali_dvfs_clk = mali_dvfs_control; if (_mali_osk_atomic_read(&bottomlock_status) > 0) { if (level < bottom_lock_step) level = bottom_lock_step; } return level; }