void control_test(double t) { int i; if(t > 50) { set_cpu_freq(1.6); for(i = 0; i < NUM_PWS_CHANNELS; i++) pws_i_control[i] = 3.0; } else { set_cpu_freq(2.8); for(i = 0; i < NUM_PWS_CHANNELS; i++) pws_i_control[i] = 0.3; } }
static void print_stuff() { printf("tmr now = %ss\n", time_now_f()); printf("SDK version: %s\n", system_get_sdk_version()); printf("APP version: %s built: %s %s\n", BUILD_DATE, __DATE__, __TIME__); printf("CPU freq was %d\n", system_get_cpu_freq()); printf("CPU freq = %d\n", set_cpu_freq(160)); printf("tmr now = %ss\n", time_now_f()); printf("tout = %sV\n", ffp(3, read_tout(0)*123/10)); printf("vdd = %sV\n", ffp(3, read_vdd())); print_mac(STATION_IF); print_mac(SOFTAP_IF); print_ip_info(SOFTAP_IF); print_ip_info(STATION_IF); printf("tmr now = %ss\n", time_now_f()); printf("sleeping 2s\n"); system_deep_sleep(2*1000000); vTaskDelete(NULL); }
/*! * This function disables the DVFS module. */ void stop_dvfs(void) { u32 reg = 0; unsigned long flags; u32 curr_cpu; unsigned long old_loops_per_jiffy; if (dvfs_core_is_active) { /* Mask dvfs irq, disable DVFS */ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); /* FSVAIM=1 */ reg |= MXC_DVFSCNTR_FSVAIM; __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); curr_wp = 0; if (!high_bus_freq_mode) set_high_bus_freq(1); curr_cpu = clk_get_rate(cpu_clk); if (curr_cpu != cpu_wp_tbl[curr_wp].cpu_rate) set_cpu_freq(curr_wp); if (cpufreq_trig_needed == 1) { /*Fix loops-per-jiffy */ old_loops_per_jiffy = loops_per_jiffy; loops_per_jiffy = dvfs_cpu_jiffies(old_loops_per_jiffy, curr_cpu/1000, clk_get_rate(cpu_clk) / 1000); #if defined(CONFIG_CPU_FREQ) /* Fix CPU frequency for CPUFREQ. */ cpufreq_get(0); #endif cpufreq_trig_needed = 0; } spin_lock_irqsave(&mxc_dvfs_core_lock, flags); reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); reg = (reg & ~MXC_DVFSCNTR_DVFEN); __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags); dvfs_core_is_active = 0; clk_disable(dvfs_clk); } printk(KERN_DEBUG "DVFS is stopped\n"); }
/* * This function resets the system. It is called by machine_restart(). * * @param mode indicates different kinds of resets */ void arch_reset(char mode) { unsigned long reg; unsigned long reg_1 = 0xffffffff; doze_disable(); reg = __raw_readl(MXC_CCM_CGR0); reg |= (MXC_CCM_CGR0_ESDHC1_MASK | MXC_CCM_CGR0_ESDHC2_MASK | MXC_CCM_CGR0_ESDHC3_MASK | MXC_CCM_CGR0_CSPI1_MASK | MXC_CCM_CGR0_CSPI2_MASK); __raw_writel(reg, MXC_CCM_CGR0); reg = __raw_readl(MXC_CCM_CGR3); reg |= MXC_CCM_CGR3_IIM_MASK; __raw_writel(reg, MXC_CCM_CGR3); printk(KERN_INFO "MX35 arch_reset\n"); if (in_interrupt() || kernel_oops_counter) { mxc_wd_reset(); return; } local_irq_enable(); /* Clear out bit #1 in MEMA */ pmic_write_reg(REG_MEM_A, (0 << 1), (1 << 1)); /* Turn on bit #1 */ pmic_write_reg(REG_MEM_A, (1 << 1), (1 << 1)); /* Turn off VSD */ pmic_write_reg(REG_MODE_1, (0 << 18), (1 << 18)); cpufreq_suspended = 1; set_cpu_freq(512000000); mdelay(100); peri_pll_enable(); __raw_writel(reg_1, MXC_CCM_CGR0); __raw_writel(reg_1, MXC_CCM_CGR1); __raw_writel(reg_1, MXC_CCM_CGR2); __raw_writel(reg_1, MXC_CCM_CGR3); mdelay(100); /* Memory Hold Mode */ mx35_power_off(); }
int change_freq(int dir) { double f_next; if(dir >= 0) f_next = f_curr + options_opt.control_params.fstep; else f_next = f_curr - options_opt.control_params.fstep; if(f_next >= FREQ_MIN-1e-4 && f_next <= FREQ_MAX+1e-4) { f_curr = f_next; assert(set_cpu_freq(f_curr)); return 1; } else return 0; }
/*! * This function disables the DVFS module. */ void stop_dvfs(void) { u32 reg = 0; unsigned long flags; u32 curr_cpu; if (dvfs_core_is_active) { /* Mask dvfs irq, disable DVFS */ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); /* FSVAIM=1 */ reg |= MXC_DVFSCNTR_FSVAIM; __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); curr_wp = 0; if (!high_bus_freq_mode) set_high_bus_freq(1); curr_cpu = clk_get_rate(cpu_clk); if (curr_cpu != cpu_wp_tbl[curr_wp].cpu_rate) { set_cpu_freq(curr_wp); #if defined(CONFIG_CPU_FREQ) if (cpufreq_trig_needed == 1) { cpufreq_trig_needed = 0; cpufreq_update_policy(0); } #endif } spin_lock_irqsave(&mxc_dvfs_core_lock, flags); reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); reg = (reg & ~MXC_DVFSCNTR_DVFEN); __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags); dvfs_core_is_active = 0; clk_disable(dvfs_clk); } printk(KERN_DEBUG "DVFS is stopped\n"); }
void pll_init(void) { SYSCTL_RCC2_R |= SYSCTL_RCC2_USERCC2; SYSCTL_RCC2_R |= SYSCTL_RCC2_BYPASS2; SYSCTL_RCC_R &= ~SYSCTL_RCC_XTAL_M; SYSCTL_RCC_R |= SYSCTL_RCC_XTAL_16MHZ; SYSCTL_RCC2_R &= ~SYSCTL_RCC2_OSCSRC2_M; SYSCTL_RCC2_R |= SYSCTL_RCC2_OSCSRC2_MO; SYSCTL_RCC2_R &= ~SYSCTL_RCC2_PWRDN2; SYSCTL_RCC2_R |= SYSCTL_RCC2_DIV400; SYSCTL_RCC2_R &= ~SYSCTL_RCC2_SYSDIV2_M; SYSCTL_RCC2_R &= ~SYSCTL_RCC2_SYSDIV2LSB; //((2*sysdiv) + 1 + lsb) sysdiv = 3 , lsb = 1; set_cpu_freq(3,1); while((SYSCTL_RIS_R & SYSCTL_RIS_PLLLRIS) == 0); SYSCTL_RCC2_R &= ~SYSCTL_RCC2_BYPASS2; }
/* * Use mach_cpu_init() for .data section copy as board_early_init_f() will be * too late: initf_dm() will use a value of "av_" variable from not yet * initialized (by copy) area. */ int mach_cpu_init(void) { int offset; /* Don't relocate U-Boot */ gd->flags |= GD_FLG_SKIP_RELOC; /* Copy data from ROM to RAM */ u8 *src = __rom_end; u8 *dst = __ram_start; while (dst < __ram_end) *dst++ = *src++; /* Enable debug uart */ #define DEBUG_UART_BASE 0x80014000 #define DEBUG_UART_DLF_OFFSET 0xc0 write_aux_reg(DEBUG_UART_BASE + DEBUG_UART_DLF_OFFSET, 1); offset = fdt_path_offset(gd->fdt_blob, "/cpu_card/core_clk"); if (offset < 0) return offset; gd->cpu_clk = fdtdec_get_int(gd->fdt_blob, offset, "clock-frequency", 0); if (!gd->cpu_clk) return -EINVAL; /* If CPU freq > 100 MHz, divide eFLASH clock by 2 */ if (gd->cpu_clk > 100000000) { u32 reg = readl(AHBCKDIV); reg &= ~(0xF << 8); reg |= 2 << 8; writel(reg, AHBCKDIV); } return set_cpu_freq(gd->cpu_clk); }
static void dvfs_core_work_handler(struct work_struct *work) { u32 fsvai; u32 reg; u32 curr_cpu; int ret = 0; int maxf = 0, minf = 0; int low_freq_bus_ready = 0; int bus_incr = 0, cpu_dcr = 0; low_freq_bus_ready = low_freq_bus_used(); /* Check DVFS frequency adjustment interrupt status */ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); fsvai = (reg & MXC_DVFSCNTR_FSVAI_MASK) >> MXC_DVFSCNTR_FSVAI_OFFSET; /* Check FSVAI, FSVAI=0 is error */ if (fsvai == FSVAI_FREQ_NOCHANGE) { /* Do nothing. Freq change is not required */ goto END; } curr_cpu = clk_get_rate(cpu_clk); /* If FSVAI indicate freq down, check arm-clk is not in lowest frequency 200 MHz */ if (fsvai == FSVAI_FREQ_DECREASE) { if (curr_cpu == cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate) { minf = 1; if (low_bus_freq_mode) goto END; } else { /* freq down */ curr_wp++; if (curr_wp >= cpu_wp_nr) { curr_wp = cpu_wp_nr - 1; goto END; } if (curr_wp == cpu_wp_nr - 1 && !low_freq_bus_ready) { minf = 1; dvfs_load_config(1); } else { cpu_dcr = 1; } } } else { if (curr_cpu == cpu_wp_tbl[0].cpu_rate) { maxf = 1; goto END; } else { if (!high_bus_freq_mode) { /* bump up LP freq first. */ bus_incr = 1; dvfs_load_config(2); } else { /* freq up */ curr_wp = 0; maxf = 1; dvfs_load_config(0); } } } low_freq_bus_ready = low_freq_bus_used(); if ((curr_wp == cpu_wp_nr - 1) && (!low_bus_freq_mode) && (low_freq_bus_ready) && !bus_incr) { if (cpu_dcr) ret = set_cpu_freq(curr_wp); if (!cpu_dcr) { set_low_bus_freq(); dvfs_load_config(3); } else { dvfs_load_config(2); cpu_dcr = 0; } } else { if (!high_bus_freq_mode) set_high_bus_freq(1); if (!bus_incr) ret = set_cpu_freq(curr_wp); bus_incr = 0; } END: /* Set MAXF, MINF */ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); reg = (reg & ~(MXC_DVFSCNTR_MAXF_MASK | MXC_DVFSCNTR_MINF_MASK)); reg |= maxf << MXC_DVFSCNTR_MAXF_OFFSET; reg |= minf << MXC_DVFSCNTR_MINF_OFFSET; /* Enable DVFS interrupt */ /* FSVAIM=0 */ reg = (reg & ~MXC_DVFSCNTR_FSVAIM); reg |= FSVAI_FREQ_NOCHANGE; /* LBFL=1 */ reg = (reg & ~MXC_DVFSCNTR_LBFL); reg |= MXC_DVFSCNTR_LBFL; __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); /*Unmask GPC1 IRQ */ reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr); reg &= ~MXC_GPCCNTR_GPCIRQM; __raw_writel(reg, dvfs_data->gpc_cntr_reg_addr); #if defined(CONFIG_CPU_FREQ) if (cpufreq_trig_needed == 1) { cpufreq_trig_needed = 0; cpufreq_update_policy(0); } #endif }
/*! * This function disables the DVFS module. */ void stop_dvfs(void) { u32 reg = 0; unsigned long flags; u32 curr_cpu; int cpu; #ifndef CONFIG_SMP unsigned long old_loops_per_jiffy; #endif if (dvfs_core_is_active) { /* Mask dvfs irq, disable DVFS */ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); /* FSVAIM=1 */ reg |= MXC_DVFSCNTR_FSVAIM; __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); curr_op = 0; mutex_lock(&bus_freq_mutex); if (!high_bus_freq_mode) { mutex_unlock(&bus_freq_mutex); set_high_bus_freq(1); } else mutex_unlock(&bus_freq_mutex); curr_cpu = clk_get_rate(cpu_clk); if (curr_cpu != cpu_op_tbl[curr_op].cpu_rate) { set_cpu_freq(curr_op); /*Fix loops-per-jiffy */ #ifdef CONFIG_SMP for_each_online_cpu(cpu) per_cpu(cpu_data, cpu).loops_per_jiffy = dvfs_cpu_jiffies(per_cpu(cpu_data, cpu).loops_per_jiffy, curr_cpu/1000, clk_get_rate(cpu_clk) / 1000); #else old_loops_per_jiffy = loops_per_jiffy; loops_per_jiffy = dvfs_cpu_jiffies(old_loops_per_jiffy, curr_cpu/1000, clk_get_rate(cpu_clk) / 1000); #endif #if defined (CONFIG_CPU_FREQ) /* Fix CPU frequency for CPUFREQ. */ for (cpu = 0; cpu < num_online_cpus(); cpu++) cpufreq_get(cpu); #endif } spin_lock_irqsave(&mxc_dvfs_core_lock, flags); reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); reg = (reg & ~MXC_DVFSCNTR_DVFEN); __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags); dvfs_core_is_active = 0; clk_disable(dvfs_clk); } printk(KERN_DEBUG "DVFS is stopped\n"); }
static void dvfs_core_work_handler(struct work_struct *work) { u32 fsvai; u32 reg; u32 curr_cpu = 0; int ret = 0; int low_freq_bus_ready = 0; int bus_incr = 0, cpu_dcr = 0; #ifdef CONFIG_ARCH_MX5 int disable_dvfs_irq = 0; #endif int cpu; low_freq_bus_ready = low_freq_bus_used(); /* Check DVFS frequency adjustment interrupt status */ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); fsvai = (reg & MXC_DVFSCNTR_FSVAI_MASK) >> MXC_DVFSCNTR_FSVAI_OFFSET; /* Check FSVAI, FSVAI=0 is error */ if (fsvai == FSVAI_FREQ_NOCHANGE) { /* Do nothing. Freq change is not required */ goto END; } curr_cpu = clk_get_rate(cpu_clk); /* If FSVAI indicate freq down, check arm-clk is not in lowest frequency*/ if (fsvai == FSVAI_FREQ_DECREASE) { if (curr_cpu <= cpu_op_tbl[cpu_op_nr - 1].cpu_rate) { minf = 1; mutex_lock(&bus_freq_mutex); if (low_bus_freq_mode) { mutex_unlock(&bus_freq_mutex); goto END; } else mutex_unlock(&bus_freq_mutex); } else { /* freq down */ curr_op++; maxf = 0; if (curr_op >= cpu_op_nr) { curr_op = cpu_op_nr - 1; goto END; } cpu_dcr = 1; dvfs_load_config(curr_op); } } else { if (curr_cpu == cpu_op_tbl[0].cpu_rate) { maxf = 1; goto END; } else { mutex_lock(&bus_freq_mutex); if (!high_bus_freq_mode && dvfs_config_setpoint == (cpu_op_nr + 1)) { /* bump up LP freq first. */ bus_incr = 1; dvfs_load_config(cpu_op_nr); } else { /* freq up */ curr_op = 0; maxf = 1; minf = 0; dvfs_load_config(0); } mutex_unlock(&bus_freq_mutex); } } low_freq_bus_ready = low_freq_bus_used(); mutex_lock(&bus_freq_mutex); if ((curr_op == cpu_op_nr - 1) && (!low_bus_freq_mode) && (low_freq_bus_ready) && !bus_incr) { if (!minf) set_cpu_freq(curr_op); /* If dvfs_core_op is greater than cpu_op_nr, it implies * we support LPAPM mode for this platform. */ if (dvfs_core_op > cpu_op_nr) { set_low_bus_freq(); dvfs_load_config(cpu_op_nr + 1); } mutex_unlock(&bus_freq_mutex); } else { if (!high_bus_freq_mode) { mutex_unlock(&bus_freq_mutex); set_high_bus_freq(1); } else mutex_unlock(&bus_freq_mutex); if (!bus_incr) ret = set_cpu_freq(curr_op); bus_incr = 0; } END: if (cpufreq_trig_needed == 1) { /*Fix loops-per-jiffy */ #ifdef CONFIG_SMP for_each_online_cpu(cpu) per_cpu(cpu_data, cpu).loops_per_jiffy = dvfs_cpu_jiffies(per_cpu(cpu_data, cpu).loops_per_jiffy, curr_cpu / 1000, clk_get_rate(cpu_clk) / 1000); #else u32 old_loops_per_jiffy = loops_per_jiffy; loops_per_jiffy = dvfs_cpu_jiffies(old_loops_per_jiffy, curr_cpu/1000, clk_get_rate(cpu_clk) / 1000); #endif #if defined (CONFIG_CPU_FREQ) /* Fix CPU frequency for CPUFREQ. */ for (cpu = 0; cpu < num_online_cpus(); cpu++) cpufreq_get(cpu); #endif cpufreq_trig_needed = 0; } /* Set MAXF, MINF */ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); reg = (reg & ~(MXC_DVFSCNTR_MAXF_MASK | MXC_DVFSCNTR_MINF_MASK)); reg |= maxf << MXC_DVFSCNTR_MAXF_OFFSET; reg |= minf << MXC_DVFSCNTR_MINF_OFFSET; /* Enable DVFS interrupt */ /* FSVAIM=0 */ reg = (reg & ~MXC_DVFSCNTR_FSVAIM); reg |= FSVAI_FREQ_NOCHANGE; /* LBFL=1 */ reg = (reg & ~MXC_DVFSCNTR_LBFL); reg |= MXC_DVFSCNTR_LBFL; __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); /*Unmask GPC1 IRQ */ reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset); reg &= ~MXC_GPCCNTR_GPCIRQM; __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); }
void *ref1(void*){ int target_fps = 0; int target_Ug = 0; int target_Uc = 0; start_sampling = 1; int fps; int Ug; static unsigned long long Ug_bp,Ug_tp; get_gpu_time(&Ug_bp,&Ug_tp); int Uc; static unsigned long long Uc_bp,Uc_tp; get_cpu_time(4,&Uc_bp,&Uc_tp); int Fc,Fg; while(true){ if(game == -1){sleep(1);start_sampling=1;continue;} Fc=get_cpu_freq(0); Fg=get_gpu_freq(); //printf("Sample%d Fc=%d,Fg=%d,Uc=%d,Ug=%d\n",start_sampling,get_cpu_freq(0),get_gpu_freq(),Uc,Ug); if(start_sampling == 1){ fps = get_fps(binder); Uc = get_cpu_util(4,&Uc_bp,&Uc_tp); Ug = get_gpu_util(&Ug_bp,&Ug_tp); printf("Sample%d Fc=%d,Fg=%d,Uc=%d,Ug=%d\n",start_sampling,Fc,Fg,Uc,Ug); if(target_fps < fps)target_fps = fps; if(target_Uc < Uc)target_Uc = Uc; if(target_Ug < Ug)target_Ug = Ug; set_cpu_freq(0,FL[3]); set_gpu_freq(GFL[4]); start_sampling=2; sleep(1);continue; }else if(start_sampling == 2){ fps = get_fps(binder); Uc = get_cpu_util(4,&Uc_bp,&Uc_tp); Ug = get_gpu_util(&Ug_bp,&Ug_tp); printf("Sample%d Fc=%d,Fg=%d,Uc=%d,Ug=%d\n",start_sampling,Fc,Fg,Uc,Ug); if(target_fps < fps)target_fps = fps; if(target_Uc < Uc)target_Uc = Uc; if(target_Ug < Ug)target_Ug = Ug; set_cpu_freq(0,FL[10]); set_gpu_freq(GFL[0]); start_sampling=3; sleep(1);continue; }else if(start_sampling == 3){ fps = get_fps(binder); Uc = get_cpu_util(4,&Uc_bp,&Uc_tp); Ug = get_gpu_util(&Ug_bp,&Ug_tp); printf("Sample%d Fc=%d,Fg=%d,Uc=%d,Ug=%d\n",start_sampling,Fc,Fg,Uc,Ug); if(target_fps < fps)target_fps = fps; if(target_Uc < Uc)target_Uc = Uc; if(target_Ug < Ug)target_Ug = Ug; set_cpu_freq(0,FL[10]); set_gpu_freq(GFL[4]); start_sampling=4; sleep(1);continue; }else if(start_sampling == 4){ printf("Sample%d Fc=%d,Fg=%d\n",start_sampling,get_cpu_freq(0),get_gpu_freq()); printf("Q : %d , Ug : %d , Uc : %d\n",target_fps,target_Ug,target_Uc); start_sampling=5; } fps = get_fps(binder); int fps_dev = (target_fps - fps)*100/target_fps; static int FL_point = freq_level-2; static int pre_FL = FL_point; static int GFL_point = gpu_freq_level-1; static int pre_GFL = GFL_point; int CPU_Sensitive = 1; int Fc_adj = 0; int Fg_adj = 0; int Ug_adj = 0; if(fps_dev > 10){ //printf("UP! %d %d %d\n",fps,target_fps,fps_dev); Uc = get_cpu_util(4,&Uc_bp,&Uc_tp); Ug = get_gpu_util(&Ug_bp,&Ug_tp); int fps_dif = (target_fps - fps); int Uc_dev = (target_Uc - Uc)*100/target_Uc; int Ug_dev = (target_Ug - Ug)*100/target_Ug; if(CPU_Sensitive){ //CPU Sensitive Fc_adj = (double)fps_dif * reciprocal(Coef_Fc2Q[game]) + FL[FL_point]; Ug_adj = Ug + (double)fps_dif * reciprocal(Coef_Ug2Q[game]); if(Ug_adj > target_Ug){ Fg_adj = (double)(Ug_adj - target_Ug) * -reciprocal(Coef_Fg2Ug[game]) + GFL[GFL_point]; } }else{ //GPU Sensitive Fg_adj = (double)fps_dif * reciprocal(Coef_Fg2Q[game]) + GFL[GFL_point]; Ug_adj = Ug + (double)fps_dif * reciprocal(Coef_Uc2Q[game]); if(Ug_adj > target_Ug){ Fc_adj = (double)(Ug_adj - target_Ug) * -reciprocal(Coef_Fc2Uc[game]) + FL[FL_point]; } } while(FL_point < freq_level && FL[FL_point] < Fc_adj)FL_point++; while(GFL_point < gpu_freq_level && GFL[GFL_point] < Fg_adj)GFL_point++; if(FL_point != pre_FL){ if(FL_point > freq_level-2){ FL_point = freq_level-2; }else if(FL_point < 2){ FL_point = 2; } pre_FL = FL_point; set_cpu_freq(0,FL[FL_point]); } if(GFL_point != pre_GFL){ if(GFL_point > gpu_freq_level-1){ GFL_point = gpu_freq_level-1; }else if(GFL_point < 0){ GFL_point = 0; } pre_GFL = GFL_point; set_gpu_freq(GFL[GFL_point]); } }else if(fps_dev <= 10){ //printf("DOWN! POWER SAVE %d %d %d\n",fps,target_fps,fps_dev); Uc = get_cpu_util(4,&Uc_bp,&Uc_tp); Ug = get_gpu_util(&Ug_bp,&Ug_tp); int Uc_dev = target_Uc - Uc; int Ug_dev = target_Ug - Ug; if(Uc_dev*100/Uc > 10) Fc_adj = (double)(Uc_dev) * reciprocal(Coef_Fc2Uc[game]) + FL[FL_point]; if(Ug_dev*100/Ug > 10) Fg_adj = (double)(Ug_dev) * reciprocal(Coef_Fg2Ug[game]) + GFL[GFL_point]; while(FL_point > 0 && FL[FL_point] > Fc_adj)FL_point--; while(GFL_point > 0 && GFL[GFL_point] > Fg_adj)GFL_point--; if(FL_point != pre_FL){ if(FL_point > freq_level-2){ FL_point = freq_level-2; }else if(FL_point < 2){ FL_point = 2; } pre_FL = FL_point; set_cpu_freq(0,FL[FL_point]); } if(GFL_point != pre_GFL){ if(GFL_point > gpu_freq_level-1){ GFL_point = gpu_freq_level-1; }else if(GFL_point < 0){ GFL_point = 0; } pre_GFL = GFL_point; set_gpu_freq(GFL[GFL_point]); } } sleep(1); } return 0; }
static void dvfs_core_work_handler(struct work_struct *work) { u32 fsvai; u32 reg; u32 curr_cpu; int ret = 0; int low_freq_bus_ready = 0; int bus_incr = 0, cpu_dcr = 0; unsigned long old_loops_per_jiffy; GALLEN_DBGLOCAL_BEGIN(); low_freq_bus_ready = low_freq_bus_used(); curr_cpu = clk_get_rate(cpu_clk); /* Check DVFS frequency adjustment interrupt status */ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); fsvai = (reg & MXC_DVFSCNTR_FSVAI_MASK) >> MXC_DVFSCNTR_FSVAI_OFFSET; /* Check FSVAI, FSVAI=0 is error */ if (fsvai == FSVAI_FREQ_NOCHANGE) { GALLEN_DBGLOCAL_RUNLOG(0); /* Do nothing. Freq change is not required */ goto END; } curr_cpu = clk_get_rate(cpu_clk); /* If FSVAI indicate freq down, check arm-clk is not in lowest frequency*/ if (fsvai == FSVAI_FREQ_DECREASE) { GALLEN_DBGLOCAL_RUNLOG(1); if (curr_cpu == cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate) { GALLEN_DBGLOCAL_RUNLOG(2); minf = 1; if (low_bus_freq_mode) { GALLEN_DBGLOCAL_RUNLOG(3); goto END; } } else { GALLEN_DBGLOCAL_RUNLOG(4); /* freq down */ curr_wp++; maxf = 0; if (curr_wp >= cpu_wp_nr) { GALLEN_DBGLOCAL_RUNLOG(5); curr_wp = cpu_wp_nr - 1; goto END; } cpu_dcr = 1; dvfs_load_config(curr_wp); } } else { GALLEN_DBGLOCAL_RUNLOG(6); if (curr_cpu == cpu_wp_tbl[0].cpu_rate) { GALLEN_DBGLOCAL_RUNLOG(7); maxf = 1; goto END; } else { GALLEN_DBGLOCAL_RUNLOG(8); if (!high_bus_freq_mode && dvfs_config_setpoint == (cpu_wp_nr + 1)) { GALLEN_DBGLOCAL_RUNLOG(9); /* bump up LP freq first. */ bus_incr = 1; dvfs_load_config(cpu_wp_nr); } else { GALLEN_DBGLOCAL_RUNLOG(10); /* freq up */ curr_wp = 0; maxf = 1; minf = 0; dvfs_load_config(0); } } } low_freq_bus_ready = low_freq_bus_used(); if ((curr_wp == cpu_wp_nr - 1) && (!low_bus_freq_mode) && (low_freq_bus_ready) && !bus_incr) { GALLEN_DBGLOCAL_RUNLOG(11); if (!minf) { GALLEN_DBGLOCAL_RUNLOG(12); set_cpu_freq(curr_wp); } /* If dvfs_core_wp is greater than cpu_wp_nr, it implies * we support LPAPM mode for this platform. */ if (dvfs_core_wp > cpu_wp_nr) { GALLEN_DBGLOCAL_RUNLOG(13); set_low_bus_freq(); dvfs_load_config(cpu_wp_nr + 1); } } else { GALLEN_DBGLOCAL_RUNLOG(14); if (!high_bus_freq_mode) { GALLEN_DBGLOCAL_RUNLOG(15); set_high_bus_freq(1); } if (!bus_incr) { GALLEN_DBGLOCAL_RUNLOG(16); ret = set_cpu_freq(curr_wp); } bus_incr = 0; } printk("current wp=%d\n",curr_wp); if (cpufreq_trig_needed == 1) { GALLEN_DBGLOCAL_RUNLOG(17); /*Fix loops-per-jiffy */ old_loops_per_jiffy = loops_per_jiffy; loops_per_jiffy = dvfs_cpu_jiffies(old_loops_per_jiffy, curr_cpu/1000, clk_get_rate(cpu_clk) / 1000); #if defined(CONFIG_CPU_FREQ) /* Fix CPU frequency for CPUFREQ. */ cpufreq_get(0); #endif cpufreq_trig_needed = 0; } END: /* Set MAXF, MINF */ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR); reg = (reg & ~(MXC_DVFSCNTR_MAXF_MASK | MXC_DVFSCNTR_MINF_MASK)); reg |= maxf << MXC_DVFSCNTR_MAXF_OFFSET; reg |= minf << MXC_DVFSCNTR_MINF_OFFSET; /* Enable DVFS interrupt */ /* FSVAIM=0 */ reg = (reg & ~MXC_DVFSCNTR_FSVAIM); reg |= FSVAI_FREQ_NOCHANGE; /* LBFL=1 */ reg = (reg & ~MXC_DVFSCNTR_LBFL); reg |= MXC_DVFSCNTR_LBFL; __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR); /*Unmask GPC1 IRQ */ reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset); reg &= ~MXC_GPCCNTR_GPCIRQM; __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset); GALLEN_DBGLOCAL_END(); }