#include #include #include #include #include static struct cpufreq_driver puma_driver; static struct cpufreq_frequency_table puma_frequency_table[] = { { .frequency = 400000000 , .index = 1 }, { .frequency = 200000000 , .index = 2 }, /*--- { .frequency = 133333333 , .index = 3 }, ---*/ /*--- { .frequency = 100000000 , .index = 4 }, ---*/ /*--- { .frequency = 50000000 , .index = 5 }, ---*/ /*--- { .frequency = 25000000 , .index = 6 }, ---*/ { .frequency = CPUFREQ_TABLE_END } }; static int puma5_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { unsigned int tab_index = 23; unsigned int new_speed = 0; struct cpufreq_freqs freqs; unsigned int cur = puma_get_clock(avm_clock_id_cpu); #if 0 unsigned int cur = puma_get_clock(avm_clock_id_cpu); unsigned int new_ppcr; struct cpufreq_freqs freqs; switch(relation){ case CPUFREQ_RELATION_L: new_ppcr = sa11x0_freq_to_ppcr(target_freq); if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max) new_ppcr--; break; case CPUFREQ_RELATION_H: new_ppcr = sa11x0_freq_to_ppcr(target_freq); if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) && (sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min)) new_ppcr--; break; } freqs.old = cur; freqs.new = sa11x0_ppcr_to_freq(new_ppcr); freqs.cpu = 0; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); if (freqs.new > cur) puma5_set_new_speed(cur, freqs.new); PPCR = new_ppcr; if (freqs.new < cur) puma5_set_new_speed(cur, freqs.new); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); return 0; #else cpufreq_frequency_table_target(policy, puma_frequency_table, target_freq, relation, &tab_index); printk(KERN_ERR "[%s] cpufreq_frequency_table_target returned tab_index=%d \n", __FUNCTION__, tab_index); new_speed = puma_frequency_table[tab_index].frequency; printk(KERN_ERR "[%s] setting frequency to %d \n", __FUNCTION__, new_speed ); freqs.old = cur; freqs.new = new_speed; freqs.cpu = 0; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); puma_set_clock(avm_clock_id_cpu, new_speed); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); return 0; #endif } static int __init puma5_cpu_init(struct cpufreq_policy *policy) { if (policy->cpu != 0) return -EINVAL; #if 0 policy->cur = policy->min = policy->max = puma_get_clock(avm_clock_id_cpu); policy->cpuinfo.min_freq = 100000; policy->cpuinfo.max_freq = 400000; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; #else cpufreq_frequency_table_cpuinfo(policy, puma_frequency_table); #endif return 0; } int puma5_verify_speed(struct cpufreq_policy *policy) { #if 0 unsigned int tmp; if (policy->cpu) return -EINVAL; cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); /* make sure that at least one frequency is within the policy */ tmp = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->min)] * 100; if (tmp > policy->max) policy->max = tmp; cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); #endif return cpufreq_frequency_table_verify(policy, puma_frequency_table); } unsigned int puma5_getspeed(unsigned int cpu) { if (cpu != 0){ return -EINVAL; } else { return puma_get_clock(avm_clock_id_cpu); } } static struct cpufreq_driver puma_driver = { .flags = CPUFREQ_STICKY, .verify = puma5_verify_speed, .target = puma5_target, .get = puma5_getspeed, .init = puma5_cpu_init, .name = "puma5_cpufreq", }; #if defined(CONFIG_ARCH_PUMA5) static int __init puma5_register_cpufreq(void) { printk(KERN_ERR "[%s] Registering Puma Cpu-Freq-Driver\n", __FUNCTION__); return cpufreq_register_driver(&puma_driver); } arch_initcall(puma5_register_cpufreq); #endif