/* * Copyright 2015 Sigma Designs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Sigma Designs"); MODULE_DESCRIPTION("cpufreq driver for Tangox"); static struct cpufreq_frequency_table freq_table[] = { { .driver_data = 1 }, { .driver_data = 2 }, { .driver_data = 3 }, { .driver_data = 5 }, { .driver_data = 9 }, { .driver_data = 54 }, { .frequency = CPUFREQ_TABLE_END } }; static int tangox_target(struct cpufreq_policy *policy, unsigned int idx) { // TODO: MUST CHECK FOR IDLE BEFORE CALLING clk_set_rate() return clk_set_rate(policy->clk, freq_table[idx].frequency * 1000); } #define FAST_RAMP_SPEED 15 /* in kHz per nanosecond */ static int tangox_cpu_init(struct cpufreq_policy *policy) { struct cpufreq_frequency_table *p; unsigned int freq, transition_latency; policy->clk = clk_get_sys("cpu_clk", NULL); freq = clk_get_rate(policy->clk) / 1000; transition_latency = freq / FAST_RAMP_SPEED; for (p = freq_table; p->frequency != CPUFREQ_TABLE_END; ++p) { p->frequency = freq / p->driver_data; } return cpufreq_generic_init(policy, freq_table, transition_latency); } static struct cpufreq_driver tangox_cpufreq_driver = { .name = "tangox-cpufreq", .init = tangox_cpu_init, .verify = cpufreq_generic_frequency_table_verify, .target_index = tangox_target, .get = cpufreq_generic_get, .exit = cpufreq_generic_exit, .attr = cpufreq_generic_attr, }; static int __init tangox_cpufreq_init(void) { return cpufreq_register_driver(&tangox_cpufreq_driver); } static void __exit tangox_cpufreq_exit(void) { cpufreq_unregister_driver(&tangox_cpufreq_driver); } module_init(tangox_cpufreq_init); module_exit(tangox_cpufreq_exit);