int mali_dvfs_bottom_lock_push(int lock_step) { int prev_status = _mali_osk_atomic_read(&bottomlock_status); if (prev_status < 0) { MALI_PRINT(("gpu bottom lock status is not valid for push\n")); return -1; } // not a bad idea to limit locking to 4th step, so let's leave this -gm if (samsung_rev() < EXYNOS4412_REV_2_0) lock_step = min(lock_step, MALI_DVFS_STEPS - 2); else lock_step = min(lock_step, MALI_DVFS_STEPS - 1); if (bottom_lock_step < lock_step) { bottom_lock_step = lock_step; if (get_mali_dvfs_status() < lock_step) { mali_regulator_set_voltage(mali_dvfs[lock_step].vol, mali_dvfs[lock_step].vol); mali_clk_set_rate(mali_dvfs[lock_step].clock, mali_dvfs[lock_step].freq); set_mali_dvfs_current_step(lock_step); } } return _mali_osk_atomic_inc_return(&bottomlock_status); }
static mali_bool mali_dvfs_status(u32 utilization) { unsigned int nextStatus = 0; unsigned int curStatus = 0; mali_bool boostup = MALI_FALSE; static int stay_count = 0; /* to prevent frequent switch */ MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization)); /*decide next step*/ curStatus = get_mali_dvfs_status(); nextStatus = decideNextStatus(utilization); MALI_DEBUG_PRINT(1, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep)); /*if next status is same with current status, don't change anything*/ if ((curStatus != nextStatus && stay_count == 0)) { /*check if boost up or not*/ if (nextStatus > maliDvfsStatus.currentStep) boostup = 1; /*change mali dvfs status*/ if (!change_mali_dvfs_status(nextStatus,boostup)) { MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); return MALI_FALSE; } stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount; } else { if (stay_count > 0) stay_count--; } return MALI_TRUE; }
static mali_bool mali_dvfs_status(u32 utilization) { unsigned int nextStatus = 0; unsigned int curStatus = 0; static unsigned int tmpStatus; mali_bool boostup = MALI_FALSE; static int stay_count = 5; #ifdef EXYNOS4_ASV_ENABLED static mali_bool asv_applied = MALI_FALSE; #endif MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization)); #ifdef EXYNOS4_ASV_ENABLED if (asv_applied == MALI_FALSE) { mali_dvfs_table_update(); change_mali_dvfs_status(1, 0); asv_applied = MALI_TRUE; return MALI_TRUE; } #endif /*decide next step*/ curStatus = get_mali_dvfs_status(); nextStatus = decideNextStatus(utilization); MALI_DEBUG_PRINT(1, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep)); if (curStatus < nextStatus) { /* Case 1: clock up directly */ boostup = 1; if (!change_mali_dvfs_status(nextStatus, boostup)) return MALI_FALSE; stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount; } else if (curStatus > nextStatus) { if (stay_count == 0) { /* Case 2: clock down */ boostup = 0; nextStatus = tmpStatus; if (!change_mali_dvfs_status(nextStatus, boostup)) return MALI_FALSE; stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount; } else { /* Case 3: clock down, wait until staycount is 0 */ tmpStatus = nextStatus; stay_count--; } } else { /* Case 4: clock same - reset staycount */ stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount; } return MALI_TRUE; }
static mali_bool mali_dvfs_status(u32 utilization) { unsigned int nextStatus = 0; unsigned int curStatus = 0; mali_bool boostup = MALI_FALSE; #ifdef EXYNOS4_ASV_ENABLED static mali_bool asv_applied = MALI_FALSE; #endif static int stay_count = 5; // to prevent frequent switch MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization)); #ifdef EXYNOS4_ASV_ENABLED if (asv_applied == MALI_FALSE) { mali_dvfs_table_update(); change_mali_dvfs_status(0,0); asv_applied = MALI_TRUE; return MALI_TRUE; } #endif /*decide next step*/ curStatus = get_mali_dvfs_status(); nextStatus = decideNextStatus(utilization); MALI_DEBUG_PRINT(1, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep)); /*if next status is same with current status, don't change anything*/ if(curStatus != nextStatus) { /*check if boost up or not*/ if(maliDvfsStatus.currentStep < nextStatus) { boostup = 1; stay_count = 5; } else if (maliDvfsStatus.currentStep > nextStatus){ stay_count--; } if( boostup == 1 || stay_count <= 0){ /*change mali dvfs status*/ if (!change_mali_dvfs_status(nextStatus,boostup)) { MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); return MALI_FALSE; } boostup = 0; stay_count = 5; } } else stay_count = 5; return MALI_TRUE; }
static mali_bool mali_dvfs_status(u32 utilization) { unsigned int nextStatus = 0; unsigned int curStatus = 0; mali_bool boostup = MALI_FALSE; static int stay_count = 0; #ifdef EXYNOS4_ASV_ENABLED static mali_bool asv_applied = MALI_FALSE; #endif MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization)); #ifdef EXYNOS4_ASV_ENABLED if (asv_applied == MALI_FALSE) { mali_dvfs_table_update(); change_mali_dvfs_status(1, 0); asv_applied = MALI_TRUE; return MALI_TRUE; } #endif /*decide next step*/ curStatus = get_mali_dvfs_status(); nextStatus = decideNextStatus(utilization); MALI_DEBUG_PRINT(1, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep)); /*if next status is same with current status, don't change anything*/ if ((curStatus != nextStatus && stay_count == 0)) { /*check if boost up or not*/ if (nextStatus > maliDvfsStatus.currentStep) boostup = 1; /*change mali dvfs status*/ if (!change_mali_dvfs_status(nextStatus,boostup)) { MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); return MALI_FALSE; } stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount; } else { if (stay_count > 0) stay_count--; } return MALI_TRUE; }
int mali_dvfs_bottom_lock_push(int lock_step) { int prev_status = _mali_osk_atomic_read(&bottomlock_status); if (prev_status < 0) { MALI_PRINT(("gpu bottom lock status is not valid for push\n")); return -1; } if (bottom_lock_step < lock_step) { bottom_lock_step = lock_step; if (get_mali_dvfs_status() < lock_step) { mali_regulator_set_voltage(mali_dvfs[lock_step].vol, mali_dvfs[lock_step].vol); mali_clk_set_rate(mali_dvfs[lock_step].clock, mali_dvfs[lock_step].freq); set_mali_dvfs_current_step(lock_step); } } return _mali_osk_atomic_inc_return(&bottomlock_status); }
void mali_dvfs_status_update(u32 utilization) { mali_dvfs_status curStatus = MALI_DVFS_BUTT; mali_dvfs_status nextStatus = MALI_DVFS_BUTT; MALI_DEBUG_PRINT(3, ("mali_dvfs_status: utilization = %d with count %d \n",utilization,g_mali_dfs_var.dfs_StayCount)); s_auwUtilization[g_mali_dfs_var.dfs_StayCount] = utilization; g_mali_dfs_var.dfs_StayCount++; /*count the dvfs utilization and cache them*/ if (g_mali_dfs_var.dfs_StayCount < MALI_UTILIZATION_NUM) { /*wait for counter time out*/ return; } g_mali_dfs_var.dfs_StayCount = 0; /*decide next step*/ curStatus = get_mali_dvfs_status(); nextStatus = decideNextStatus(); MALI_DEBUG_PRINT(3, ("nextStatus %d, currentStep %d \n", nextStatus, g_stMaliDvfsStatus.currentStep)); /*if next status is same with current status, don't change anything*/ if (nextStatus != MALI_DVFS_HOLD) { pwrctrl_dfs_gpu_target((s32)nextStatus - (s32)MALI_DVFS_HOLD); /*update the dvfs action status*/ g_stMaliDvfsStatus.currentStep = nextStatus; } return; }
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 ((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; }